feat(docs): GET /api/docs/resolve 路径解析端点#38
Merged
Conversation
新增 DocPathService + DocsResolveController,将任意输入路径 (含 /zh|en/ locale 前缀、历史重命名路径)解析为 canonical URL。 - normalize():strip locale 前缀、去 fragment、去尾斜杠 - SQL UNION:docs.path_current(前缀 content/)+ doc_paths.path(前缀 app/) - @Cacheable("doc-resolve"):key = normalize 后的路径,避免 /zh/ 和 /docs/ 重复缓存 - SaTokenConfigure 白名单加 /api/docs/resolve - application.properties cache-names 加 doc-resolve Smoke test 通过: /zh/docs/community/dev-tips/git101 → 301 /docs/community/dev-tips/git101 /docs/nonexistent/page → 404 无 satoken → 301(不是 401)
Contributor
There was a problem hiding this comment.
Pull request overview
该 PR 为前端 Block 3 增加一个“文档路径解析”能力:将带 locale 前缀的旧路径(如 /zh/docs/...)解析为不带 locale 的 canonical /docs/...,并通过后端 301 重定向输出,解决生产旧路径 404 的问题。
Changes:
- 新增
DocPathService:规范化输入路径并从docs/doc_paths查询 canonical/docs/...,并使用 Caffeine 缓存。 - 新增
GET /api/docs/resolve端点:命中则返回 301 Location,未命中返回 404。 - 配置变更:加入 Sa-Token 白名单、注册新增 cache name。
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/main/resources/application.properties | 注册新增的 doc-resolve 缓存名 |
| src/main/java/com/involutionhell/backend/docs/service/DocPathService.java | 新增路径规范化 + DB 查询 + 缓存的解析服务 |
| src/main/java/com/involutionhell/backend/docs/controller/DocsResolveController.java | 新增公开解析端点并返回 301/404 |
| src/main/java/com/involutionhell/backend/common/config/SaTokenConfigure.java | 将 /api/docs/resolve 加入 Sa-Token 白名单 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+70
to
+75
| // docs.path_current 前缀是 content/,doc_paths.path 前缀是 app/ | ||
| String sql = """ | ||
| SELECT canonical_path FROM ( | ||
| SELECT regexp_replace( | ||
| regexp_replace(d.path_current, '^content', ''), | ||
| '(/index)?\\.(mdx|md)$', '' |
Comment on lines
+36
to
+45
| String normalize(String path) { | ||
| if (path == null) return null; | ||
| // 去 fragment | ||
| int h = path.indexOf('#'); | ||
| if (h >= 0) path = path.substring(0, h); | ||
| // strip locale 前缀 /zh/ 或 /en/ | ||
| path = path.replaceFirst("^/(zh|en)/", "/"); | ||
| // 去尾斜杠(根路径 "/" 不动) | ||
| if (path.length() > 1 && path.endsWith("/")) { | ||
| path = path.substring(0, path.length() - 1); |
Comment on lines
+63
to
+68
| @Cacheable(value = "doc-resolve", key = "T(com.involutionhell.backend.docs.service.DocPathService).normalizeStatic(#inputPath)") | ||
| public Optional<String> resolveCanonical(String inputPath) { | ||
| String normalizedPath = normalize(inputPath); | ||
| if (normalizedPath == null || normalizedPath.isBlank()) { | ||
| return Optional.empty(); | ||
| } |
| # 注册所有需要的缓存名(之前写了两次被覆盖,eventSummary 实际没注册导致缓存失效) | ||
| # docHistory 用来缓存 GitHub commits API 结果,避免给每次文档页访问都打 GitHub 限流 | ||
| spring.cache.cache-names=topDocs,eventSummary,docHistory,githubRepos,zoteroItems,leaderboard | ||
| spring.cache.cache-names=topDocs,eventSummary,docHistory,githubRepos,zoteroItems,leaderboard,doc-resolve |
Comment on lines
+32
to
+40
| @GetMapping("/api/docs/resolve") | ||
| public ResponseEntity<Void> resolve(@RequestParam String path) { | ||
| Optional<String> canonical = docPathService.resolveCanonical(path); | ||
| if (canonical.isPresent()) { | ||
| return ResponseEntity.status(HttpStatus.MOVED_PERMANENTLY) | ||
| .location(URI.create(canonical.get())) | ||
| .build(); | ||
| } | ||
| return ResponseEntity.notFound().build(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
生产
/zh/docs/community/*(带 locale 前缀的旧路径)已 404,需要后端提供路径解析端点供前端 Block 3 使用。新增内容
DocPathServicenormalize(path):strip/zh|en/locale 前缀、去 fragment(#)、去尾斜杠resolveCanonical(inputPath):UNION 查询docs.path_current(前缀content/)和doc_paths.path(前缀app/),返回 canonical/docs/...路径@Cacheable("doc-resolve"):key = normalize 后的路径,保证/zh/docs/...和/docs/...命中同一缓存条目DocsResolveControllercanonical 不带 locale,前端 Block 3 负责拼 locale 后再做最终跳转。
配置变更
SaTokenConfigure:加.notMatch("/api/docs/resolve")白名单application.properties:spring.cache.cache-names加doc-resolveSmoke test 结果(本地 8081)
/zh/docs/community/dev-tips/git101/docs/community/dev-tips/git101/docs/community/dev-tips/git101/docs/community/dev-tips/git101/en/docs/community/dev-tips/git101/docs/community/dev-tips/git101/docs/nonexistent/page/docs/community/dev-tips/git101