V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
jerrry
V2EX  ›  程序员

Restful API URL 设计问题

  •  
  •   jerrry · 2023-04-02 22:11:02 +08:00 · 2081 次点击
    这是一个创建于 602 天前的主题,其中的信息可能已经有所发展或是发生改变。

    假如有一个博客系统,有用户管理模块,文章模块,评论模块,并且使用 JWT Token (可以解析出 userId )

    那用户的文章列表、文章详情、文章的评论应该怎样设计呢?

    第一种:

    • /users/:userId/posts UserController
    • /users/:userId/posts/:postId UserController
    • /users/:userId/posts/:postId/comments UserController
    • /users/:userId/posts/:postId/comments/:commentId UserController

    也就是全都放在 UserController 里

    第二种:

    • /posts PostController
    • /posts/:postId PostController
    • /posts/:postId/comments CommentController
    • /posts/:postId/comments/:commentId CommentController

    第二种:

    • /posts PostController
    • /posts/:postId PostController
    • /comments?post-id=xx CommentController
    • /comments/:commentId CommentController

    第一种的话,因为 userId 是从用户的 headers.token 中解析出来的,所以我觉得没必要前面加上 /users/:userId,除非需要管理功能,但是管理功能的 api 本来就是要跟用户端的分开来的。而且这样的话所有功能都放在 UserController 里了。

    第二种的话在 CommentController 里前缀是 /posts 有点奇怪。

    所以个人偏向第三种。

    11 条回复    2023-04-03 20:52:37 +08:00
    AnroZ
        1
    AnroZ  
       2023-04-02 23:12:09 +08:00   ❤️ 1
    我们是选择第三种。具体什么原因忘了,应该是为了减少歧义,方便沟通。
    liununu
        2
    liununu  
       2023-04-02 23:20:19 +08:00 via iPhone   ❤️ 1
    一种划分思路,从 Post / Comment 这两个资源的生命周期,依赖关系,聚合关系出发。
    比如一个 Comment 一定仅是出现并关联在一个具体的 Post 上,不能完全创建的话,那就是 /posts/:postId/comments
    zapper
        3
    zapper  
       2023-04-02 23:24:07 +08:00   ❤️ 1
    9 敏,有两个第二种
    根据我为数不多的“看过猪跑”的经验来看,/comments?post-id= 这种比较常见,例如 wordpress 的
    https://example.com/wp-json/wp/v2/comments
    参数可以接 author 可以接 post

    前面的看起来是现代化的写法但是看起来总是觉得怪怪的,而且第一种全部在 UserController 里面不太好吧
    iseki
        4
    iseki  
       2023-04-02 23:30:31 +08:00   ❤️ 1
    如果选用第二种的话考虑下要么每个 post 的 comments 都有独立的序列(比如楼层号),要么考虑下两者冲突时怎么弄;第三种的话,那就是个 id 了,没法在那个地方放楼层号了;
    daweiba
        5
    daweiba  
       2023-04-02 23:53:11 +08:00   ❤️ 1
    非常基础

    /posts
    /posts/:id
    /posts/:id/comments
    /comments/:id
    leoskey
        6
    leoskey  
       2023-04-03 10:53:31 +08:00   ❤️ 1
    个人经验,在第二种中 /posts/:postId/comments/:commentId 更适合操作在资源里无主键的集合或属性,例如 /posts/:postId/post-name , /posts/:postId/attachments
    jerrry
        7
    jerrry  
    OP
       2023-04-03 14:19:42 +08:00
    @liununu 那这个 /posts/:postId/comments 是放在 PostController 还是 CommentController 呢?
    jerrry
        8
    jerrry  
    OP
       2023-04-03 14:23:27 +08:00
    @daweiba 那 /posts/:id/comments 是放在 PostController 还是 CommentController 里好呢?如果放在 PostController 里,那是调用 PostService 还是 CommentService 里来实现 findPostComments 方法呢?不知道哪种设计更好
    daweiba
        9
    daweiba  
       2023-04-03 17:45:23 +08:00
    @jerrry
    ```
    class PostsController < ApplicationController

    # /posts
    def index

    end
    # /posts/:id
    def show


    end
    # /posts/:id/comments
    def comments

    end
    end

    ```
    ```
    class CommentsController < ApplicationController

    # /comments
    def index

    end
    # /comments/:id
    def show


    end

    end

    ```
    liununu
        10
    liununu  
       2023-04-03 19:41:12 +08:00 via iPhone
    个人觉得 PostController 更合适一点,因为从属上是「某个文章里面的评论」
    iseki
        11
    iseki  
       2023-04-03 20:52:37 +08:00 via Android   ❤️ 1
    各放各的 controller ,不要被路由左右了,你看 ktor 那种写法,你就不会纠结这些有的没的了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3140 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 13:54 · PVG 21:54 · LAX 05:54 · JFK 08:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.