@api-ts/io-ts-http (英语)
客户端和服务器端对 HTTP 请求进行( 取消) 序列化的运行时间类型
目录
前言
此软件包扩展 io-ts(双胞胎) 具有实用功能 输入 HTTP 请求。 从那里开始使用此软件包所需的基础知识 .
导言
io- ts- http 是 api- ts 规格的定义语言, 定义 API 网络断接合同,以任意的精确度。 Web 服务器可以使用 io-ts-http spec在运行时解析HTTP请求,并编码了HTTP响应. 客户 可以使用io-ts-http spec在编译时执行API兼容性,并编码 请求到服务器并解码回复.
概览
图书馆的主要功能是 httpRequest。您可以使用它来构建解码器
它能将一个通用的 HTTP 请求解析为更精细的类型。 通用 HTTP
请求应符合下列接口:
interface GenericHttpRequest {
params: {
[K: string]: string;
};
query: {
[K: string]: string | string[];
};
headers: {
[K: string]: string;
};
body?: unknown;
}
这里, params 代表路径参数和 query 以最小方式解析查询
字符串参数(基本上只是将查询字符串和
url 解析值). 这个 httpRequest 函数可以和来自
io-ts 以构建一个能够验证、解析和编码这些代码的合并编码器
通用 HTTP 请求为更精细的对象。 例如:
import { httpRequest, optional } from '@api-ts/io-ts-http';
import { DateFromISOString, NumberFromString } from 'io-ts-types';
const ExampleHttpRequest = httpRequest({
query: {
id: NumberFromString,
time: optional(DateFromISOString),
},
});
这将构建一个可被赋予任意 HTTP 请求的解码器,并确保它
包含一个 id 参数,也可以选择检查 time 参数,以及
如果存在,验证并分析为 Date如果解码成功,则
生成值的类型为:
type ExampleDecodedResult = {
id: number;
time?: Date;
};
此类型由 TypeScript 正确推断,可以用于这样的分解:
import { pipe } from 'fp-ts/function';
import * as E from 'fp-ts/Either';
const { id, time } = pipe(
ExampleHttpRequest.decode(request),
E.getOrElseW((decodeErrors) => {
someErrorHandler(decodeErrors);
}),
);
获取请求的参数验证和解析为一行。 这些解码器也可以是 用于从客户端获取发出请求的类别安全性。 一个API 客户端可以假设有如下方法:
apiClient.request(route, ExampleHttpRequest, {
id: 1337,
time: new Date(),
});
如果服务器和客户端都为请求使用相同的编码器,那么它就会变成 可能编码API合同(或至少尽可能多编码) 在类型系统中表达),因此,有人呼叫API可以相信 如果参数类型检查,服务器将正确解释请求.
示例
让我们定义一个假设 message-user 服务。 常规
顶级导出为
apiSpec
值;例如:
apiSpec
import { apiSpec } from '@api-ts/io-ts-http';
import { GetMessage, CreateMessage } from './routes/message';
import { GetUser, CreateUser, PatchUser, UpdateUser, DeleteUser } from './routes/user';
/**
* message-user service
*
* @version 1.0.0
*/
export const API = apiSpec({
'api.v1.message': {
get: GetMessage,
post: CreateMessage,
},
'api.v1.user': {
get: GetUser,
post: CreateUser,
put: UpdateUser,
delete: DeleteUser,
patch: PatchUser,
},
});
这个 apiSpec 和一些名称 httpRoutes (单位:千美元){Get|Create}Message, (中文(简体) ),
财务报告和审定财务报表 {Get|Create|Update|Delete}User(中文(简体) ) 我们下面讨论。 。 。 .
目前,如果添加
@versionJSDoc 对导出 API 的标记, 它将会是 用作 APIversion生成 OpenAPI 计划时。 支持其它标签 今后可能会增加.
顶级导出 message-user-types 实值 API,我们将其定义为 apiSpec
有两个终点 api/v1/message 财务报告和审定财务报表 api/v1/user编辑 api/v1/message 结束点
对 GET 财务报告和审定财务报表 POST 第二个重排时的动词 GET, (中文(简体) ), POST, (中文(简体) ), PUT,以及
DELETE 使用动词 httpRoutes 定义 ./routes/message以下为
httpRoutes 定义 ./routes/message。 。 。 .
httpRoute
import * as t from 'io-ts';
import { httpRoute, httpRequest } from '@api-ts/io-ts-http';
export const GetMessage = httpRoute({
path: '/message/{id}',
method: 'GET',
request: httpRequest({
params: {
id: t.string,
},
}),
response: {
200: t.type({
id: t.string,
message: t.string,
}),
404: t.type({
error: t.string,
}),
},
});
export const CreateMessage = httpRoute({
path: '/message',
method: 'POST',
request: httpRequest({
body: {
message: t.string,
},
}),
response: {
200: t.type({
id: t.string,
message: t.string,
}),
404: t.type({
error: t.string,
}),
},
});
第一个导入是 io-ts 软件包。 通常是进口的 as t 用于:
描述数据属性的类型。 再说一遍,审查
io-ts(双胞胎) 关于如何使用更多背景的文档
和这个包裹.
礛 httpRoute 财务报告和审定财务报表 httpRequest 已导入。 我们将审查
httpRequest 下面,但首先,让我们回顾一下 GetMessage
httpRoute。 。 。 .
export const GetMessage = httpRoute({
path: '/message/{id}',
method: 'GET',
request: httpRequest({
params: {
id: t.string,
},
}),
response: {
200: t.type({
id: t.string,
message: t.string,
}),
404: t.type({
error: t.string,
}),
},
});
httpRoute编号
apiSpec用户
httpRoute编号
定义 path, (中文(简体) ), method, (中文(简体) ), request 财务报告和审定财务报表 response 一条路线.
path
路线 path 附带可能的路径变量。 您应该包围变量
括号类似 {name},并且对 request 代码 params 属性.
method
路线 method 这是
HTTP 请求方法 用于
为这条路线。 在我们 GetMessage 实例 method 实值 GET,在我们
PostMessage 实例 method 实值 POST。 。 。 .
request
路线 request 显示 httpRequest 函数。 这将是
说明如下.
response
路线 response 描述可能
HTTP 回复 路径可以
生产。 键值对 response 对象为 HTTP 状态代码
编辑 io-ts 类型。 在我们 GetMessage 实例,a 200 状态
反应产生JSON物体的有效载荷,具有两个特性, message 是一个
string 财务报告和审定财务报表 id 这也是一个 string,则a 404 jSON的载荷
单属性对象 error 是一个 String。 。 。 .
httpRequest
使用 httpRequest 以构建在请求中传递到路径的预期类型。 单位
我们的榜样 GetMessage
export const GetMessage = httpRoute({
path: '/message/{id}',
method: 'GET',
request: httpRequest({
params: {
id: t.string,
},
}),
// ...
});
httpRequests 共有4个可选属性: params (举个例子),
query, (中文(简体) ), headers,以及 body。 。 。 .
params
params 是代表 URL 中路径参数类型的对象。 任意 URL
参数 path 财产 httpRoute 必须在
params 财产的财产 httpRequest。我们的请求有一个 URL 参数它是
期待, id中此参数的类型 params 对象
我们的 httpRequest。 。 。 .
query
query 是表示在结尾通过查询参数传递的值的对象
一个 URL。 下面的例子使用一个新的路径, GetMessages对于我们的API
搜索特定信件 author数字 :
export const GetMessages = httpRoute({
path: '/messages',
method: 'GET',
request: httpRequest({
query: {
author: t.string,
},
}),
// ...
});
headers
headers 是一个代表
HTTP 信头 随身携带
请求.
body
body 是代表该对象类型的一个对象
HTTP 车体 页:1
请求。 这通常是JSON的物体 这个 CreateMessage httpRoute 以我们为榜样
使用该 body 属性 :
export const CreateMessage = httpRoute({
path: '/message',
method: 'POST',
request: httpRequest({
body: {
message: t.string,
},
}),
// ...
});
正在解码 httpRequest
当你解码时 httpRequests 使用 io-ts 帮助者,请求的属性是
像这样平地
import { DateFromISOString, NumberFromString } from 'io-ts-types';
// build an httpRequest with one parameter id and a body with content and a timestamp
const Request = httpRequest({
params: {
id: NumberFromString,
},
body: {
content: t.string,
timestamp: DateFromISOString,
},
});
// use io-ts to get the type of the Request
type Request = t.TypeOf<typeof Request>;
// same as
type Request = {
id: number;
content: string;
timestamp: Date;
};