Restful API URL 设计问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
jerrry
V2EX    程序员

Restful API URL 设计问题

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

    假如有一个博客系统,有用户管理模块,文章模块,评论模块,并且使用 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     Solana     1091 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 23:31 PVG 07:31 LAX 15:31 JFK 18:31
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86