fontcolor_theme

HTTP

处理 HTTP 请求是服务器最为人所知的任务之一。它将输入(HTTP 请求)转换为输出(HTTP 响应)并执行特定任务。客户端可以通过多种方式在 HTTP 请求中向服务器发送数据,服务器必须正确读取并处理这些数据。除了 HTTP body,还可以通过 HTTP query 或 HTTP header 传递值。数据实际如何处理取决于服务器,由服务器定义客户端应当将这些值发送到哪里以及以何种方式发送。

这里的首要任务不仅是正确执行用户所期望的操作,还要正确转换(反序列化)并验证来自 HTTP 请求的任何输入。

HTTP 请求在服务器上经过的流水线可以多种多样且复杂。许多简单的 HTTP 库在给定路由中只传递 HTTP 请求和 HTTP 响应,并期望开发者直接处理 HTTP 响应。中间件 API 允许按需扩展这条流水线。

Express 示例

const http = express();
http.get('/user/:id', (request, response) => {
    response.send({id: request.params.id, username: 'Peter' );
});

这非常适合简单用例,但随着应用程序的增长会很快变得混乱,因为所有输入和输出都必须手动序列化或反序列化并进行验证。同时,还必须考虑如何从应用本身获取诸如数据库抽象之类的对象和服务。这迫使开发者在其之上构建一层架构来映射这些必需的功能。

相反,Deepkit 的 HTTP 库利用了 TypeScript 和依赖注入的力量。基于定义的类型,任何值的序列化/反序列化与验证都会自动进行。它还允许像上面的示例那样通过函数式 API 定义路由,或通过控制器类定义路由,以满足不同架构的需求。

它既可以与现有的 HTTP 服务器一起使用(如 Node 的 http 模块),也可以与 Deepkit 框架一起使用。两种 API 变体都可以访问依赖注入容器,从而方便地从应用中获取诸如数据库抽象和配置等对象。

示例:函数式 API

import { Positive } from '@deepkit/type';
import { http, HttpRouterRegistry } from '@deepkit/http';
import { FrameworkModule } from "@deepkit/framework";

//函数式 API
const app = new App({
    imports: [new FrameworkModule()]
});
const router = app.get(HttpRouterRegistry);

router.get('/user/:id', (id: number & Positive, database: Database) => {
    //id 保证为 number 类型且为正数。
    //database 由 DI 容器注入。
    return database.query(User).filter({ id }).findOne();
});

app.run();

类控制器 API

import { Positive } from '@deepkit/type';
import { http, HttpRouterRegistry } from '@deepkit/http';
import { FrameworkModule } from "@deepkit/framework";
import { User } from "discord.js";

//控制器 API
class UserController {
    constructor(private database: Database) {
    }

    @http.GET('/user/:id')
    user(id: number & Positive) {
        return this.database.query(User).filter({ id }).findOne();
    }
}

const app = new App({
    controllers: [UserController],
    imports: [new FrameworkModule()]
});
English中文 (Chinese)한국어 (Korean)日本語 (Japanese)Deutsch (German)