ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

RealWorld 后端 API 端点规范全解:Conduit 的 18 个 REST 接口、认证模型与官方测试验证

2026/9/5 20:03:50 拓冰建站 浏览量
RealWorld 后端 API 端点规范全解:Conduit 的 18 个 REST 接口、认证模型与官方测试验证 RealWorld 后端 API 端点规范全解Conduit 的 18 个 REST 接口、认证模型与官方测试验证【免费下载链接】realworldThe mother of all demo apps — Exemplary fullstack Medium.com clone powered by React, Angular, Node, Django, and many more项目地址: https://gitcode.com/GitHub_Trending/re/realworldRealWorldThe mother of all demo apps为所有后端实现定义了一套统一的 API 契约本文以仓库中的端点规范文档为核心完整梳理认证头约定、用户/文章/评论/收藏/标签五大类共 18 个端点的请求与响应约定、查询参数与字段要求并结合仓库内的 OpenAPI 规范、Hurl/Bruno 测试套件说明如何对本地实现做端到端自动化验证。读完后你可以直接按此契约实现一个 RealWorld 兼容的 Conduit 风格后端并用官方测试脚本检验其正确性。1. 认证头约定Authorization: Token ...RealWorld 的受保护接口统一通过请求头携带 JWT 令牌规范文档给出的标准形式为Authorization: Token jwt.token.here令牌来自注册POST /api/users或登录POST /api/users/login成功后的响应中的user.token字段该约定在 OpenAPI 规范中对应apiKey类型的 securityScheme其描述明确要求“访问受保护资源时必须已通过注册或登录获得有效 JWT并通过Authorization头传入”见 openapi.yml 第 912 行起的securitySchemes定义官方 Hurl 测试中每个需要认证的请求都写成Authorization: Token {{token}}见 specs/api/hurl/auth.hurl 第 42 行起这正是实现时需要对齐的格式。2. 用户与认证端点4 个2.1 登录POST /api/users/login无需认证请求体示例来自 endpoints.md{ user:{ email: jakejake.jake, password: jakejake } }必填字段email、password。成功返回一个 User 对象结构见第 7 节。OpenAPI 规范中该操作为Login成功状态码为200错误分支包括401凭据无效与422字段校验失败见 openapi.yml 第 22 行起。2.2 注册POST /api/users无需认证请求体示例{ user:{ username: Jacob, email: jakejake.jake, password: jakejake } }必填字段email、username、password成功返回 User。从 openapi.yml 第 39 行起的CreateUser定义可以看出注册成功的状态码是201而非 200用户名或邮箱冲突时返回409 Conflict——实现时注意区分这两个状态码Hurl 测试中的断言也是HTTP 201见 specs/api/hurl/auth.hurl 第 1 行起。2.3 获取当前用户GET /api/user需要认证返回当前登录用户对应的 User 对象。对应 OpenAPI 中的GetCurrentUser。2.4 更新用户PUT /api/user需要认证请求体示例{ user:{ email: jakejake.jake, bio: I like to skateboard, image: https://i.stack.imgur.com/xHWG8.jpg } }接受的字段email、username、password、image、bio。从源码结构看测试套件对更新接口的约束远比“字段可传”严格specs/api/hurl/errors_auth.hurl 覆盖了以下边界行为email/username/password传空字符串应被拒绝422password必须至少 8 个字符18 字符以下简单短密码会被拒64 字符长密码应接受可空字段bio、image传空字符串时应规范化为null并持久化显式传null对可空字段是合法操作。这些行为对实现中的“空串归一化”逻辑如 ORM 序列化前把转成None提出了明确要求。3. 个人主页与关注端点3 个3.1 获取个人主页GET /api/profiles/:username认证可选游客可访问登录后following字段才有意义返回 Profile 对象。用户不存在时返回404。3.2 关注用户POST /api/profiles/:username/follow3.3 取消关注DELETE /api/profiles/:username/follow两者均需要认证、无额外请求参数成功时返回操作后的 Profile 对象目标用户不存在时返回404对应 OpenAPI 中FollowUserByUsername/UnfollowUserByUsername见 openapi.yml 第 112 行起。Hurl 测试 specs/api/hurl/profiles.hurl 验证了 follow 后following: true、unfollow 后回落为false的持久化语义。4. 文章端点7 个文章是 RealWorld 数据模型的核心端点最多。4.1 文章列表GET /api/articles默认全局返回最新文章支持以下查询参数均见 endpoints.md参数作用示例默认值tag按标签过滤?tagAngularJS不过滤author按作者用户名过滤?authorjake不过滤favorited过滤某用户收藏的文章?favoritedjake不过滤limit限制返回条数?limit2020offset跳过条数分页游标?offset00认证可选按最新创建时间降序返回 多篇文章articles数组 articlesCount。limit/offset两个参数在 OpenAPI 中定义为共享参数openapi.yml 第 895 行起的offsetParam、limitParam分页行为由 specs/api/hurl/pagination.hurl 验证limit1 时先返回最新一篇offset1 后翻页拿到次新一篇。4.2 关注流GET /api/articles/feed支持同样的limit与offset参数必须认证返回当前用户所关注用户发布的文章按最新优先排序。specs/api/hurl/feed.hurl 验证了“新用户 feed 为空 → 关注后 feed 出现其文章”的完整链路。4.3 获取单篇文章GET /api/articles/:slug无需认证按 slug 返回 单篇文章slug 不存在返回404。4.4 创建文章POST /api/articles需要认证请求体示例{ article: { title: How to train your dragon, description: Ever wonder how?, body: You have to believe, tagList: [reactjs, angularjs, dragons] } }必填字段title、description、body可选字段tagList字符串数组。标题/描述/正文任一为空字符串时返回422对应 specs/api/hurl/errors_articles.hurl 中的 09–11 组断言。4.5 更新文章PUT /api/articles/:slug需要认证可传可选字段title、description、body当title变更时slug也必须随之重新生成。请求体示例{ article: { title: Did you train your dragon? } }规范对 slug 的约定值得特别注意原文档原文slug 是文章的 URL 标识符。规范只要求它必须是唯一字符串用于 fetch/update/delete 文章——重复标题也必须产生不同的 slug。如何派生由实现自定常见做法是 title 的 kebab-case测试套件不强制任何特定格式。从源码结构看specs/api/hurl/errors_articles.hurl 中专门有两组用例12-duplicate-titles-are-allowed-each-gets-a-unique-slug两个相同标题的文章各自获得不同 slug与13-update-article-without-taglist-tags-should-be-preserved更新时不传tagList应保留原有标签传空数组则清空标签tagList为null会被拒绝——这些都是纯靠读接口列表容易漏掉的持久化细节。4.6 删除文章DELETE /api/articles/:slug需要认证且只能删除自己的文章他人删除应返回403specs/api/hurl/errors_authorization.hurl 中04-user-b-tries-to-delete-403用例验证。slug 不存在返回404。5. 评论端点3 个5.1 发表评论POST /api/articles/:slug/comments需要认证请求体示例{ comment: { body: His name was my name too. } }必填字段body成功返回创建后的 Comment 对象。文章不存在或body为空分别返回404/422。5.2 获取文章评论GET /api/articles/:slug/comments认证可选返回 多条评论。5.3 删除评论DELETE /api/articles/:slug/comments/:id需要认证。权限语义为“谁评论的谁删”非作者删除他人评论返回403且评论必须仍然存活specs/api/hurl/errors_authorization.hurl 中07/08用例显式验证了这一点specs/api/hurl/comments.hurl 中还包含“选择性删除”场景——删掉一条后另一条仍然存在。6. 收藏与标签端点3 个6.1 收藏文章POST /api/articles/:slug/favorite6.2 取消收藏DELETE /api/articles/:slug/favorite均需要认证、无额外参数成功返回 Article 对象——注意返回的是操作后的完整文章对象favorited与favoritesCount应已更新。specs/api/hurl/favorites.hurl 验证了收藏状态持久化以及第 2 节提到的?favoritedjake过滤能力。6.3 获取标签列表GET /api/tags无需认证返回字符串数组{ tags: [ reactjs, angularjs ] }7. 响应对象结构速查端点规范中的“返回 User / Profile / Article / Comment”均指向统一的响应格式文档api-response-format.md关键点Useremail、token、username、bio、imagebio/image可为nullProfileusername、bio、image、followingSingle Articleslug、title、description、body、tagList、createdAt、updatedAt、favorited、favoritesCount并内嵌authorProfileMultiple Articlesarticles数组 articlesCountCommentid、createdAt、updatedAt、body 内嵌authorProfile。响应头需保证Content-Type: application/json; charsetutf-8。一个重要的版本行为变更原文档标注自 2024-08-16 起GET /api/articles与GET /api/articles/feed不再返回文章的body字段性能考虑。因此列表接口返回的文章对象没有body只有单篇接口才有完整正文——实现时不要在这两个列表端点输出body。8. 错误码约定端点失败时的状态码语义在 error-handling.md 中统一定义422字段校验失败错误体形如{errors: {body: [cant be empty]}}字段名为键、错误消息数组为值401需要认证但未提供403请求合法但当前用户无权限404资源不存在。这套语义在各分类的 Hurl 错误测试目录中逐条落实可作为实现后的对照清单specs/api/hurl/ 下的errors_auth.hurl、errors_articles.hurl、errors_authorization.hurl、errors_comments.hurl、errors_profiles.hurl。9. 用官方测试套件验证你的实现规范文档的 Introductionintroduction.md明确OpenAPI 规范与 Hurl 测试才是契约的最终权威散文式文档与测试不一致时以测试为准。仓库提供了两套可直接对本地后端运行的测试Hurl 方式Hurl 文件是唯一事实来源见 specs/api/README.mdHOSThttp://localhost:3000/api ./run-api-tests-hurl.shrun-api-tests-hurl.sh 内部以hurl --test --jobs 1串行执行hurl/目录下全部用例并注入两个变量hostAPI 基地址脚本默认值为http://localhost:8000通常按 README 用HOST环境变量覆盖uid默认取时间戳进程号用于生成互不冲突的用户名/邮箱保证同一后端可重复运行测试。Bruno 方式交互式集合由 Hurl 自动生成并保持同步HOSThttp://localhost:3000/api ./run-api-tests-bruno.sh也可以直接用 Bruno 打开 specs/api/bruno/ 目录逐请求调试。按 specs/api/README.md 说明Bruno 集合通过make bruno-generate从 Hurl 生成并经 CI 以make bruno-check保持同步因此两套集合的覆盖面一致。10. 小结RealWorld 的后端契约由三部分构成端点清单18 个接口覆盖认证、用户、个人主页、关注、文章、评论、收藏、标签、统一响应对象格式User/Profile/Article/Comment/Tags与四类状态码语义422/401/403/404。实现时的重点难点集中在注册返回 201、更新用户时bio/image空串归一化为null、文章标题变更后重新派生 slug 且重复标题必须 slug 唯一、列表接口自 2024-08-16 起不再输出body、以及各类越权操作的 403/404 精确区分。以 specs/api/openapi.yml 为机器可读契约、以 specs/api/hurl/ 测试套件为验收基准即可交付一个完全兼容 RealWorld 规范的 Conduit 后端。【免费下载链接】realworldThe mother of all demo apps — Exemplary fullstack Medium.com clone powered by React, Angular, Node, Django, and many more项目地址: https://gitcode.com/GitHub_Trending/re/realworld创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考