@clipboard-health/json-api-nestjs (英语)
用于遵守《公约》的方便脚本工具 亚庇: 规格为 网点JS。 。 。 .
目录
安装
npm install @clipboard-health/json-api-nestjs
使用量
查询助手
为您的 API 查询创建 Zod 计划 :
import { booleanString } from "@clipboard-health/contract-core";
import {
cursorPaginationQuery,
fieldsQuery,
type FilterMap,
filterQuery,
includeQuery,
sortQuery,
} from "@clipboard-health/json-api-nestjs";
import { z } from "zod";
import type {
ArticleAttributeFields,
UserAttributeFields,
UserIncludeFields,
} from "../src/contract";
const articleFields = ["title"] as const satisfies readonly ArticleAttributeFields[];
const userFields = ["age", "dateOfBirth"] as const satisfies readonly UserAttributeFields[];
const userIncludeFields = [
"articles",
"articles.comments",
] as const satisfies readonly UserIncludeFields[];
const userFilterMap = {
age: {
filters: ["eq", "gt"],
schema: z.coerce.number().int().positive().max(125),
},
dateOfBirth: {
filters: ["gte"],
schema: z.coerce.date().min(new Date("1900-01-01")).max(new Date()),
},
isActive: {
filters: ["eq"],
schema: booleanString,
},
} as const satisfies FilterMap<UserAttributeFields>;
/**
* Disclaimer: Just because JSON:API supports robust querying doesn’t mean your service should
* implement them as they may require database indexes, which have a cost. **Implement only access
* patterns required by clients.**
*
* The spec says that if clients provide fields the server doesn’t support, it **MUST** return 400
* Bad Request, hence the `.strict()`.
*/
export const query = z
.object({
...cursorPaginationQuery(),
...fieldsQuery({ article: articleFields, user: userFields }),
...filterQuery(userFilterMap),
...sortQuery(userFields),
...includeQuery(userIncludeFields),
})
.strict();
快速查询解析器
查询助手期望 req.query 以锁定嵌入对象: ?filter[age][gt]=10 必须在
{ filter: { age: { gt: "10" } } }。快递 5 的默认值 simple 查询解析叶
filter[age][gt] 作为一平一键,所以 .strict() 以 400 和 a 拒绝查询
非限制性的,静静地放下过滤器和页码.
设置 a qs 在 Nest app 上查询解析器 。 剪贴板服务可以使用 createQueryParser() 从
@clipboard-health/api-nestjs 17.0.0或以后:
import { createQueryParser } from "@clipboard-health/api-nestjs";
import { NestFactory } from "@nestjs/core";
import { type NestExpressApplication } from "@nestjs/platform-express";
import { AppModule } from "./app.module";
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.set("query parser", createQueryParser());
await app.listen(3000);
其他应用程序可以通过调用函数 qs是因为 parse 相反,
比如说 app.set("query parser", (query: string) => qs.parse(query))。 。 。 .
oLPC的路线不需要设置: 不读 req.query。见 oRPC程序。 。 。 .
oRPC程序
查询助手在 oRPC 缩写: 程序。 OLPC 解析查询字符串本身, 所以
宣布程序 inputStructure: "detailed" 将援助者的计谋 query数字 :
import { oc } from "@orpc/contract";
import { z } from "zod";
const query = z
.object({
...cursorPaginationQuery(),
...filterQuery(userFilterMap),
...sortQuery(userFields),
})
.strict();
export const list = oc
.route({ inputStructure: "detailed", method: "GET", path: "/users" })
.input(z.object({ query }));
对于相同的查询字符串,帮助者返回的数值和验证问题与返回的相同
qs 和ts-rest,除了下面的差异. 以 OPPC 400 开头的路径 query。 。 。 .
orpcQueryParsing.test.ts 运行每个助手通过两个
解说者. @orpc/* 不是此软件包的依赖性或对等依赖性.
与 Qs 的差别
oLPC的分解器按照参数出现的顺序构建了每个键的值. 当纯值
(单位:千美元)filter[age]=10后面是同一键上的一个括号内的密钥(filter[age][gt]=5, (中文(简体) ),
filter[age][eq]=20, (中文(简体) ), filter[age][]=20它在计划看到它之前就抛弃了原值,
财务报告和审定财务报表 qs 留着吧 请求成功时没有这个值, 因此过滤器比客户端匹配更多
问取来. 帮助者无法恢复价值. 客户端每个密钥应发送一个样式: 设置操作员
首filter[age][gt]=5&filter[age]=10 工作),写 filter[age][eq]=10 明确或单独
带有逗号的值(filter[age]=10,20) (中文(简体) ). 这同样适用于 sort, (中文(简体) ), include,以及 fields
(单位:千美元)sort=age&sort[]=-age 仅保留 -age) (中文(简体) ).
较小的差异 :
- oLPC 拒绝类似原型的密钥 (
filter[__proto__][x]=1, (中文(简体) ),filter[hasOwnProperty]=1有400个 从.strict()。 。 。 .qs与allowPrototypes: false悄悄地扔下他们. - oRPC 拒绝错误的括号密钥(
filter[age]]=10)和一个空密钥(=x)与一出四百相会.qs接受第一个并忽略第二个. filter[age][eq]=10&filter[age][]=20将两个值都保留在两个解析器下,但qs命令他们20, 10缩略语10, 20。 。 。 .- oLPC没有参数限制.
qs与parameterLimit: 1000默默地将参数降于 头一千. 帮助者自己的数组限制仍然适用.
地方发展指挥部
见 package.json scripts 用于命令列表.