@clipboard-health/json-api-nestjs

中文文档
2.14.19发布于 2026/11/05MITTypeScriptCommonJS近 30 天下载 7.6万

TypeScript-friendly utilities for adhering to the JSON:API specification with NestJS.

原始使用文档
文档目录7 节
  1. Table of contents
  2. Install
  3. Usage
  4. Query helpers
  5. Express query parser
  6. oRPC procedures
  7. Local development commands

@clipboard-health/json-api-nestjs

TypeScript-friendly utilities for adhering to the JSON:API specification with NestJS.

Table of contents

Install

npm install @clipboard-health/json-api-nestjs

Usage

Query helpers

Create Zod schemas for your API's queries:

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();

Express query parser

The query helpers expect req.query to hold nested objects: ?filter[age][gt]=10 must arrive as { filter: { age: { gt: "10" } } }. Express 5's default simple query parser leaves filter[age][gt] as one flat key, so a .strict() query schema rejects the query with a 400 and a non-strict one silently drops the filter and pagination.

Set a qs query parser on the Nest app. Clipboard services can use createQueryParser() from @clipboard-health/api-nestjs 17.0.0 or later:

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);

Other apps can pass a function that calls qs's parse instead, for example app.set("query parser", (query: string) => qs.parse(query)).

oRPC routes don't need the setting: they don't read req.query. See oRPC procedures.

oRPC procedures

The query helpers work in oRPC procedures. oRPC parses the query string itself, so declare the procedure with inputStructure: "detailed" and put the helpers' schema under 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 }));

For the same query string, the helpers return the same values and the same validation issues as with qs and ts-rest, apart from the differences below. Issue paths in an oRPC 400 start with query. orpcQueryParsing.test.ts runs each helper through both parsers. @orpc/* isn't a dependency or peer dependency of this package.

Differences from qs

oRPC's parser builds each key's value in the order the parameters appear. When a plain value (filter[age]=10) is followed by a bracketed key on the same key (filter[age][gt]=5, filter[age][eq]=20, filter[age][]=20), it discards the plain value before the schema sees it, and qs keeps it. The request succeeds without that value, so a filter can match more than the client asked for. Helpers can't recover the value. Clients should send one style per key: put the operator first (filter[age][gt]=5&filter[age]=10 works), write filter[age][eq]=10 explicitly, or separate values with commas (filter[age]=10,20). The same applies to sort, include, and fields (sort=age&sort[]=-age keeps only -age).

Smaller differences:

  • oRPC rejects prototype-like keys (filter[__proto__][x]=1, filter[hasOwnProperty]=1) with a 400 from .strict(). qs with allowPrototypes: false drops them silently.
  • oRPC rejects malformed bracket keys (filter[age]]=10) and an empty key (=x) with a 400. qs accepts the first and ignores the second.
  • filter[age][eq]=10&filter[age][]=20 keeps both values under both parsers, but qs orders them 20, 10 and oRPC 10, 20.
  • oRPC has no parameter limit. qs with parameterLimit: 1000 silently drops parameters after the first 1,000. The helpers' own array limits still apply.

Local development commands

See package.json scripts for a list of commands.

版本与发布记录

@clipboard-health/json-api-nestjs 共发布 501 个版本,首次发布于 2024/10/14;过去 12 个月发布了 396 个版本。

版本发布日期距今
2.14.19latest2026/11/054 天前
2.14.182026/11/054 天前
2.14.172026/11/055 天前
2.14.162026/11/045 天前
2.14.152026/11/045 天前
2.14.142026/10/3110 天前

关于 @clipboard-health/json-api-nestjs 的常见问题

@clipboard-health/json-api-nestjs 是什么?

TypeScript-friendly utilities for adhering to the JSON:API specification with NestJS.

如何安装 @clipboard-health/json-api-nestjs?

在项目目录运行 npm install @clipboard-health/json-api-nestjs,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:zod(^3)、type-fest(^4 || ^5.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@clipboard-health/json-api-nestjs 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@clipboard-health/json-api-nestjs 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@clipboard-health/json-api-nestjs 可以商用吗?

@clipboard-health/json-api-nestjs 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@clipboard-health/json-api-nestjs 的下载量有多少?

根据 npm 官方下载统计,@clipboard-health/json-api-nestjs 在 2026/10/10 – 2026/11/08 这 30 天内被下载 76,107 次,日均约 2,537 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@clipboard-health/json-api-nestjs 还在维护吗?

最新版本 2.14.19 发布于 2026/11/05(4 天前);至今共发布 501 个版本,其中过去 12 个月发布了 396 个;首次发布于 2024/10/14。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。