ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

RealWorld 前端路由规范解析:Conduit 应用的 URL 设计、Feed 切换、分页与认证守卫

RealWorld 前端路由规范解析:Conduit 应用的 URL 设计、Feed 切换、分页与认证守卫 RealWorld 前端路由规范解析Conduit 应用的 URL 设计、Feed 切换、分页与认证守卫【免费下载链接】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官方文档中的前端路由规范routing.md是 Conduit 类应用前端实现的骨架文件它规定了全部页面 URL、认证方式、以及每个页面上的关键交互要求。本文以该规范为主体逐页拆解每一条路由的设计意图并借助仓库中的共享 Playwright E2E 测试specs/e2e/url-navigation.spec.ts、specs/e2e/navigation.spec.ts与后端端点定义specs/api/bruno说明这些路由如何与 API 参数、测试契约一一咬合。读完本文你可以直接照着规范落地一套可被官方测试套件验收的前端路由体系。一、完整路由总览原规范文档只列出了 7 组基础路由而仓库中的 selectors 契约 把它们扩展成了一张更完整的路由合同表。两套资料合并后一份合格的 RealWorld 前端实现必须支持以下全部 URL路由页面规范要求/首页 / Global Feed标签列表 文章列表 分页/?feedfollowing首页 / Your Feed已认证用户的关注流/?pageN分页 feed文章列表翻页/tag/:tag按标签筛选的首页从侧边栏点击标签进入/tag/:tag?pageN标签视图分页标签页翻页/login登录页提交后跳转//register注册页提交后跳转//editor新建文章编辑器页面/editor/:slug编辑文章带 slug 的编辑模式/settings用户设置表单 登出/profile/:username用户资料页基本信息 My Articles/profile/:username/favorites资料页收藏 tab用户收藏的文章/article/:slug文章详情页Markdown 渲染 评论区这张表来自 SELECTORS.md 的 Routes 章节它与 routing 规范文档完全一致且额外明确了/?feedfollowing和?pageN这两个查询参数式路由——它们不是独立页面而是首页的 URL 状态这正是 Conduit 路由设计的精髓用 URL 承载 feed 类型与页码使分享、前进/后退、刷新都可用。二、首页/三种数据源与侧边栏标签原规范对首页的三条要求是标签列表List of tags文章列表来源三选一Feed、Global 或按 Tag文章列表分页Pagination与 API 的映射对照 endpoints 规范 和 OpenAPI 定义specs/api/openapi.yml三种数据源分别落在不同端点上前端状态URLAPI 调用关键参数Global Feed/GET /api/articles默认按时间倒序Your Feed/?feedfollowingGET /api/articles/feed需要认证返回被关注用户的文章按标签筛选/tag/:tagGET /api/articles?tagAngularJS分页?pageNlimit/offset文档默认limit20、offset0补充两个容易遗漏的查询参数?authorjake按作者筛选和?favoritedjake按收藏者筛选——后者正是资料页 favorites tab 的数据来源见第六节。标签侧边栏的数据来自GET /api/tags无需认证返回扁平标签数组。Feed tab 的 URL 契约E2E 测试把 feed 切换定义成了硬性断言url-navigation.spec.ts未登录用户访问/时Global Feed链接必须带active类URL 保持/已登录用户点击Your FeedURL 必须变为/?feedfollowing且Your Feed链接转为 active未登录用户访问/?feedfollowing必须被重定向到/login——这就是 routing 文档隐含的feed 认证守卫要求空 feed 时应展示.empty-feed-message提示文案含 Your feed is empty并提供返回 Global Feed 的链接。从源码结构看测试还断言了两个 tab 的href属性Your Feed 固定指向/?feedfollowingGlobal Feed 固定指向/。这意味着 tab 切换不是纯前端状态而是真实的路由导航浏览器后退按钮可以直接在两种 feed 之间切换。标签导航navigation.spec.ts 验证了标签筛选链路点击侧边栏.sidebar .tag-list .tag-pill中的标签后对应标签名出现在.nav-link中并处于 active 状态且列表只显示带该标签的文章。而should paginate articles用例直接访问/tag/uniqueTag断言首页数量不超过 10 条——说明标签页也是可分页的独立 URL可以直接通过地址栏深链接进入某一页。三、/login与/registerJWT 存 localStorage原规范原文Sign in/Sign up pages (URL:/login,/register) Uses JWT (store the token in localStorage) Authentication can be easily switched to session/cookie based三条要点拆解如下。1. JWT 的存储位置是契约不只是惯例SELECTORS.md 明确规定 localStorage 的 key 必须是jwtTokenvalue 为 JWT 字符串。共享测试套件会直接读写这个 key 来注入/读取令牌SPA 模式下通过page.route()拦截 API 流量所以换 key 名会导致测试直接失败。登录后所有请求需携带请求头Authorization: Token jwt格式见 endpoints 文档。2. 提交后的跳转行为auth 辅助函数 展示了验收标准register()在/register填写input[nameusername]、input[nameemail]、input[namepassword]后点击 submit必须跳转到/login()在/login同样以跳转到/为成功标志登出则是从/settings点击 Or click here to logout 按钮并回到/。若表单校验失败错误信息必须渲染在.error-messages列表中如 That email is already taken。3. 可切换到 session/cookie 的余地规范特意说明认证可轻松切换为 session/cookie 方案。这对应测试套件的多形态设计helpers/config.ts 定义了三种TEST_MODE——spa浏览器直连 REST APIJWT 存客户端可拦截 API 流量、ssr服务端代表浏览器调用外部 API例如 httpOnly-cookie 认证的 SvelteKit/Next.js 应用、fullstack前后端一体全部走 UI 驱动。从源码结构看路由规范刻意不绑定具体认证实现前端只需要保证令牌从登录/注册响应中获得、随请求发出、持久化在约定的位置这三件事测试套件就能同时验收三种架构。四、/settings与/editor、/editor/:slug设置页/settings是唯一要求登录的纯表单页规范在 templates 文档 中给出了完整模板头像 URL、姓名、bio、邮箱、新密码五个字段一个 Update Settings 按钮对应PUT /api/user接受字段为email、username、password、image、bio以及页底的 Or click here to logout 登出按钮。E2E 契约要求输入框带name属性input[nameimage]、textarea[namebio]等以便测试定位。编辑器双模式规范将/editor新建与/editor/article-slug-here编辑并列要求同一页面组件承担两种模式/editor空表单含 Article Titleinput[nametitle]、Whats this article about?input[namedescription]、Markdown 正文textarea[namebody]、标签输入框placeholder 固定为 Enter tags以及 Publish Article 按钮提交走POST /api/articles/editor/:slug先用GET /api/articles/:slug拉取现有内容回填表单提交走PUT /api/articles/:slug。一个隐藏的细节来自 endpoints 文档当title被修改时slug也会被后端更新。这意味着编辑器提交成功后前端应当用响应体中的新 slug 更新浏览器 URL/editor/new-slug否则用户下次手动刷新会 404。这也是把slug 放 URL 里这一路由设计的代价与收益URL 天然幂等、可刷新但要求前端在保存后同步地址栏。五、/article/:slug条件渲染与客户端 Markdown原规范对文章详情页给出了四条要求每一条都对应明确的测试断言删除按钮只展示给作者。模板中Delete Article按钮危险样式.btn-outline-danger与Edit Article链接只应在当前登录用户 文章作者时渲染。跨用户越权的可行性在后端由 403 兜底errors_authorization 测试组但前端只给作者显示按钮是规范层面的 UI 要求。客户端渲染 Markdown。API 返回的body是原始 Markdown 字符串前端负责在详情页渲染成 HTML渲染结果包裹在.article-content中selectors 契约。底部评论区。评论表单textarea[placeholderWrite a comment...] Post Comment 按钮对应POST /api/articles/:slug/comments列表通过GET /api/articles/:slug/comments拉取无需认证即可阅读。删除评论按钮只展示给评论作者点击调用DELETE /api/articles/:slug/comments/:idcomments E2E 用例 与 selective-deletion Bruno 用例创建两条、删一条、验证另一条仍在分别验证了 UI 层与 API 层的删除后其余内容不丢失。六、/profile/:username与/profile/:username/favorites规范原文Profile page (URL:/profile/:username,/profile/:username/favorites) Show basic user info List of articles populated from authors created articles or authors favorited articles拆解为三个实现点基本信息用户名、bio、头像.user-info/.user-img、关注按钮POST/DELETE /api/profiles/:username/follow按钮文案在Follow {username}与Unfollow {username}间切换。头像为null或空时必须回退到 default-avatar.svg——这是 SELECTORS 契约中Default Avatar一节明确断言的行为。My Articles tab调用GET /api/articles?author:usernameFavorited Articles tab调用GET /api/articles?favorited:username并对应独立 URL/profile/:username/favorites保证 tab 可直接深链接。navigation.spec.ts 的 profile 用例 量化了验收标准用户创建 2 篇文章并收藏其中 1 篇后My Articles tab 必须显示 2 条.article-preview切到 Favorited tab 后必须恰好 1 条。空资料页0 篇文章也要优雅处理而不是报错。七、分页?pageN的 URL 语义routing 规范只写了 Pagination for list of articles 一句话但 E2E 套件把它的语义钉得很死url-navigation.spec.ts 的 Pagination 组页码进 URL点击第 2 页后URL 必须变为/tag/tag?page2且第 2 页的.page-item带active类URL 可直达直接访问/tag/tag?page2页面应加载第 2 页并高亮页码 2参数可组合Your Feed 翻页时 URL 变为/?feedfollowingpage2feed与page参数共存切换 feed 重置页码在/tag/tag?page2上点击 Global FeedURL 回到/页码参数被清除每页条数API 端limit默认 20endpoints 文档而共享 E2E 套件按每页 10 条断言15 articles 2 pages with limit 10第一页 10 条、第二页 5 条。因此前端列表请求应显式传limit10不要依赖服务端默认值。前端实现时的典型换算page从 1 起URL 语义API 的offset从 0 起即offset (page - 1) * limit。后端对这套换算的验收可见 pagination Bruno 用例limit1时articles.length 1且articlesCount为总数。八、用共享 E2E 套件验收你的路由实现本仓库自带一套可直接复用的 Playwright 测试specs/e2e其中 navigation.spec.ts 与 url-navigation.spec.ts 正是路由规范的自动化验收脚本。接入方式见 tests 文档 与 playwright.base.ts在实现仓库中继承specs/e2e/playwright.base.ts覆写baseURL指向本地 dev server必要时配置webServer启动命令通过环境变量TEST_MODE声明架构形态浏览器直连 API 的 SPA 用spa默认服务端渲染用ssr前后端一体用fullstack从源码结构看测试内部按BROWSER_API/EXTERNAL_API两个能力开关分支而非直接判断模式字符串保证实现满足 SELECTORS.md 的全部契约路由表、name属性、.feed-toggle/.article-preview/.pagination等 CSS 类、.error-messages错误列表、localStorage 的jwtTokenkey以及window.__conduit_debug__调试接口提供getToken()、getAuthState()、getCurrentUser()三个方法需要外部 demo API 时测试默认调用 helpers/config.ts 中API_BASE配置的官方 demo 地址可用环境变量覆盖该 demo API 仅允许 RealWorld 前端应用消费具体限制见 API 文档。小结RealWorld 的路由规范看似只有一张短列表实际隐含了五个可测试的约束feed 类型与页码全部进 URL/?feedfollowing、?pageN、/tag/:tag?pageN、未认证访问 feed 重定向到/login、JWT 固定存于localStorage.jwtToken、/editor/:slug在改标题后需同步新 slug、文章/评论的删除按钮按作者身份条件渲染。仓库中的 E2E 测试与 Bruno 用例逐条印证了这些约束——对照 routing 规范、SELECTORS 契约 和 端点定义 三份文档实现再用共享 Playwright 套件跑一遍导航与分页用例即可完成路由层的全部验收。【免费下载链接】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),仅供参考
返回列表