JSON:API 规范仓库实战指南:媒体类型、文档结构与本地构建
发布时间:2026/9/27 10:46:18来源:尧图网络
后端API设计【免费下载链接】json-apiA specification for building JSON APIs项目地址https://gitcode.com/gh_mirrors/js/json-api点击查看免费下载本文以 JSON:API 官方规范仓库README.md为入口系统梳理application/vnd.apijson媒体类型规范的核心语义、文档结构与媒体类型参数规则并给出在本地搭建规范站点、阅读规范、参与贡献的完整流程。读完本文你将理解 JSON:API 的顶层文档结构、资源对象与错误对象约定掌握 extensions / profiles 的用法并能够在本仓库中运行 Jekyll 站点、校验 JSON Schema 测试用例。一、仓库是什么JSON:API 规范的官方源码本仓库是 JSON:API 规范application/vnd.apijson的官方源码即 http://jsonapi.org 网站的内容来源。JSON:API 是一套如何用 JSON 构建 API的规范它同时规定了客户端如何请求资源、服务端如何响应这些请求。其核心目标是最小化客户端与服务器之间的请求次数和传输数据量同时不牺牲可读性、灵活性与可发现性discoverability。规范正文位于仓库的 _format/ 目录当前最新正式版本为 1.1见 _config.yml 中latest_version: 1.1。从仓库目录结构看除了规范正文外还包含examples/稀疏字段集sparse fieldsets、分页链接、错误对象等的完整 HTTP 示例extensions/ 与 ext/扩展与 profile 的说明及已评审的扩展如 Atomic Operations_schemas/各版本规范的 JSON Schema 测试套件与校验脚本implementations/、recommendations/、faq/、about/社区实现清单、推荐实践、FAQ 与规范历史_profiles/社区 profile 草案如 cursor-pagination 等分页类 profile。二、核心规范速览媒体类型、语义与文档结构2.1 媒体类型与内容协商所有 JSON:API 请求与响应必须使用application/vnd.apijson作为Content-Type见 _format/1.1/index.md 的 Content Negotiation 一节。该媒体类型已正式注册于 IANA。规范支持两个媒体类型参数参数用途ext指定一个或多个 扩展extension扩展名以空格分隔的 URI 列表表示profile指定一个或多个 profile同样以空格分隔的 URI 列表表示关键约束除ext与profile外不得携带其他媒体类型参数ext与profile的值必须是空格分隔U0020的 URI 列表访问该 URI应SHOULD返回其用法文档序列化时HTTP 规范要求参数值必须用引号U0022包裹例如Content-Type: application/vnd.apijson;exthttps://jsonapi.org/ext/version客户端可同时在Accept头中使用ext/profile参数并通过 quality values 表达优先级服务端若收到带不支持参数的请求应返回415 Unsupported Media Type若Accept头中所有实例都不被支持应返回406 Not Acceptable支持这些参数的服务端应在响应中设置Vary: Accept部分 CDN 中间件可能忽略 Vary 头。注意不支持 1.1 的服务端在遇到ext或profile参数时会返回415 Unsupported Media Type。2.2 规范语义、实现语义与保留语义规范将所有文档成员、查询参数与处理规则统称为规范语义specification semantics留给实现者自行定义的部分称为实现语义implementation semantics其余一切均保留给规范的未来版本使用。2.3 文档顶层结构每个 JSON:API 请求/响应文档的根必须是一个 JSON 对象且必须包含以下顶层成员之一data主数据primary dataerrors错误对象数组meta非标准的元信息对象由已应用的扩展定义的一个成员。其中data与errors不得共存于同一文档。此外可以MAY包含以下顶层成员jsonapi描述服务端实现的对象如{version: 1.1}links与整个文档相关的链接对象可含self、related、describedby与分页链接included与主数据相关的资源对象数组——但若文档没有顶层data则不得出现included。主数据primary data的形态取决于请求目标单个资源目标对应单个资源对象、单个资源标识对象或null资源集合目标对应资源对象数组、资源标识对象数组或空数组[]即使只有一个元素也必须用数组表示。2.4 资源对象与资源标识对象资源对象resource object必须包含id与type两个顶层成员例外情况是当资源对象由客户端创建、代表服务端尚不存在的新资源时id可以省略客户端可选用lid成员在文档内局部唯一标识该资源。资源对象可以包含attributes资源的部分数据relationships与其他 JSON:API 资源的关系links与资源相关的链接meta无法用 attribute 或 relationship 表示的资源级元信息。资源标识对象resource identifier object则只包含type与id以及可选的meta用于在关系链接linkage中引用资源。例如下面这个文章-作者-评论关系的典型响应出自仓库首页 index.md 的示例{ links: { self: http://example.com/articles, next: http://example.com/articles?page[offset]2, last: http://example.com/articles?page[offset]10 }, data: [{ type: articles, id: 1, attributes: { title: JSON:API paints my bikeshed! }, relationships: { author: { links: { self: http://example.com/articles/1/relationships/author, related: http://example.com/articles/1/author }, data: { type: people, id: 9 } }, comments: { links: { self: http://example.com/articles/1/relationships/comments, related: http://example.com/articles/1/comments }, data: [ { type: comments, id: 5 }, { type: comments, id: 12 } ] } } }], included: [ { type: people, id: 9, attributes: { firstName: Dan, lastName: Gebhardt } }, { type: comments, id: 5, attributes: { body: First! } } ] }顶层links.self应包含客户端用于生成该响应文档的全部查询参数含 include、fields、sort、page、filter 等使客户端无需额外信息即可刷新数据。三、扩展与 Profile在规范基础上安全演进JSON:API 通过 extensions 与 profiles 两种机制提供扩展能力详见 _format/1.1/index.md 的 Extensions 与 Profiles 小节。扩展extensions定义额外的规范语义。扩展可以新增文档成员与查询参数但不得削弱或移除既有规则也不得定义实现语义。凡是定义了新成员或新查询参数的扩展必须定义一个命名空间namespace以保证互不冲突命名空间至少一个字符只能包含a-z、A-Z、0-9且一个扩展不得定义多个命名空间。例如扩展https://jsonapi.org/ext/version可定义形如version:id: 42的资源成员HTTP/1.1 200 OK Content-Type: application/vnd.apijson;exthttps://jsonapi.org/ext/version { type: articles, id: 1, version:id: 42, attributes: { title: Rails is Omakase } }Profile用于在实现之间共享某种特定用法遵循 RFC 6906。Profile可以定义实现语义但不得新增、修改或移除规范语义不得定义除实现专属查询参数以外的查询参数。Profile 无需命名空间因为它不能定义规范语义但实现者有责任避免同时支持互相冲突的 profile。例如某个 profile 可规定timestamps属性必须为包含created/modified两个 RFC 3339 时间字段的对象HTTP/1.1 200 OK Content-Type: application/vnd.apijson;profilehttps://example.com/resource-timestamps { type: articles, id: 1, attributes: { title: Rails is Omakase, timestamps: { created: 2020-07-21T12:09:00Z, modified: 2020-07-30T10:19:01Z } } }两者最本质的区别在于扩展必须被客户端与服务端共同理解而profile 可以被任一方安全忽略。仓库首页 index.md 也提示社区创建的这类可扩展能力在历史上被统称为 profiles可在 extensions/ 页面浏览既有 profile 或创建新的。该页面列出的扩展与 profile 已经过规范编辑者评审被视为兼容基础规范、可无后向不兼容地演进且具有广泛实用性但任何扩展/profile 只要使用自有域名托管文档即使不在该列表中也是合法的。仓库中还存放了示例 profile 草案例如 _profiles/ethanresnick/cursor-pagination/含 index、max-size-exceeded、range-pagination-not-supported、unsupported-sort 等错误页面。四、错误对象统一、可机器处理的错误响应规范要求错误响应使用顶层errors数组见 _format/1.1/index.md 的 Error Objects 一节与 examples/index.md 中的完整示例。每个错误对象的成员全部可选常用成员如下成员含义id错误的唯一标识错误对象间唯一性约束仅此一项status与该错误关联的 HTTP 状态码字符串多错误响应时尤其有用code应用自定义的错误类型码比title更利于程序化处理不受本地化影响title面向人类的简短、通用错误标题detail针对本次出现的更具体的说明source指明错误来源pointer用 JSON Pointer 指向请求文档中的位置parameter指明有问题的查询参数名一个典型的校验失败响应HTTP/1.1 422 Unprocessable Entity Content-Type: application/vnd.apijson { errors: [ { status: 422, source: { pointer: /data/attributes/firstName }, title: Invalid Attribute, detail: First name must contain at least two characters. } ] }若请求体不是合法 JSON则source无从指向可只返回status与detail若问题出在查询参数则使用source.parameter例如{ source: { parameter: include } }。错误响应中不能包含顶层data但可以包含jsonapi、meta等其他顶层成员。另外注意规范本身对 400 与 422 的选择不持立场两者均可接受。五、稀疏字段集与分页链接的实操示例仓库 examples/index.md 给出了可直接对照的实战示例。稀疏字段集sparse fieldsets通过fields[type]查询参数按类型裁剪返回字段。注意关系名也是字段若在fields中省略了关系名则included中的关系数据同样不会返回。例如GET /articles?includeauthorfields[articles]title,body,authorfields[people]name HTTP/1.1响应中articles只含title、body、author字段people只含name字段。URL 中的方括号在规范要求下应做百分号编码见 _format/1.1/index.md 附录 Square Brackets in Parameter Names。分页链接分页策略由实现者自行决定常用page[number]/page[size]这类参数并在顶层links中给出first、prev、next、last或基于 offset 的self/next/lastGET /articles?page[number]3page[size]1 HTTP/1.1响应可同时在meta中放入totalPages等实现自定义的总量信息——meta成员名完全由实现决定并非规范强制。六、在本地构建与预览规范站点README 给出了在本地编辑规范文档的标准工作流整个过程依赖 Jekyll 与 Compass/SCSS依赖清单见 Gemfile包含github-pages、rake、compass、sass、launchy、redcard等。# 1. 安装依赖 $ bundle # 2. 本地起站并自动打开浏览器预览 $ bundle exec rake preview:browser启动后站点默认运行在http://localhost:9876端口配置见 _config.yml 的port: 9876。preview:browser任务的具体行为由 Rakefile 中的preview(true)实现它会同时拉起两个进程——bundle exec jekyll serve渲染站点与bundle exec scss --compass --watch stylesheets/监听 SCSS 编译等待约 2 秒后用launchy打开浏览器按 CtrlCINT 信号会同时终止这两个进程。若不想自动打开浏览器可运行bundle exec rake preview。站点构建的底层配置说明_config.yml站点 URL 为http://jsonapi.org输出目录./publicMarkdown 渲染使用 kramdownGFM 输入、rouge 高亮并配置了format、errors、profiles三个集合collection及各自默认布局latest_version: 1.1使 _format/index.md 通过 Liquid 循环自动嵌入 1.1 版规范正文站点更新后由 GitHub Pages 在gh-pages分支上自动构建发布。七、规范测试套件JSON Schema 校验除网站构建外本仓库还为规范各版本提供了 JSON Schema 测试套件位于 _schemas/ 下覆盖 1.0/1.1 的 request/response 各类有效与无效样例如顶层data与errors不得共存、资源标识必须含id/type、链接必须是合法 URI 等校验脚本为 _schemas/scripts/validator.js。按 CONTRIBUTING.md 的说明# 安装 Node 依赖package.json 已就绪 npm install # 运行全部测试文件对所有可用规范版本校验 node ./_schemas/scripts/validator.js # 等价命令 npm run test-schema常用选项--verbose更详细的输出-f relative-path只测试指定文件例如npm run test-schema -- -f _schemas/1.0/response/valid/with_success/complete.json-v version指定规范版本例如npm run test-schema -- -v 1.0。八、如何参与贡献README 与 CONTRIBUTING.md 明确了参与路径bundle安装依赖bundle exec rake preview:browser本地预览编辑规范正文 Markdown 文件主要位于 _format/ 及 _schemas/提交变更并发送 Pull Request推送到gh-pages分支后站点自动构建。社区交流渠道包括 IRCfreenode 的 #jsonapi 频道、Twitterjsonapi与官方 Discourse 论坛讨论扩展想法与正确实现/消费 JSON:API 的问题。关于规范修改与网站更新的内部不一致问题可提交到 Issue Tracker历史版本归档可参考仓库 Archive 部分提到的 RC3 版本。结语JSON:API 通过一套统一的媒体类型与文档约定把响应格式的争论bikeshedding转化为可共享的通用工具链与最佳实践——客户端围绕该规范可以高效缓存响应、甚至完全消除部分网络请求。本文以仓库 README.md 为纲梳理了媒体类型参数、文档顶层结构、资源对象、错误对象、扩展与 profile、稀疏字段集与分页等核心要素并给出了本地建站与 Schema 测试的完整命令。深入阅读规范全文建议直接打开 _format/1.1/index.md并结合 examples/ 与 _schemas/ 的测试样例逐条印证。赞分享后端API设计【免费下载链接】json-apiA specification for building JSON APIs项目地址https://gitcode.com/gh_mirrors/js/json-api点击查看免费下载相关推荐ScyllaDB 官方文档仓库全指南目录结构、写作规范与本地构建部署ScyllaDB 官方文档仓库全指南目录结构、写作规范与本地构建部署 本篇技术指南聚焦 ScyllaDB 项目仓库中的文档体系完整讲解其两级文档用户文档与数据库分布式数据库后端大数据Mastra 文档写作指南页面类型、结构规范与仓库源码验证Mastra 文档写作指南页面类型、结构规范与仓库源码验证 Mastra 开源仓库TypeScript AI 应用框架的官方文档不仅服务于人类读者还要面人工智能Agent 框架AI AgentRAG后端OpenTelemetry Go SDK 配置热更新3 条路径实现无重启动态调参OpenTelemetry Go SDK 配置热更新3 条路径实现无重启动态调参 凌晨两点流量突增你要把 trace 采样率从 100% 压到 5%一分可观测性上一篇Wand-Enhancer终极免费解锁Wand专业版完整指南下一篇终极免费解锁Wand专业版简单三步告别2小时限制的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网