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

restful api 设计问题请教

  •  
  •   chaleaochexist · 2023-12-08 14:05:30 +08:00 · 2138 次点击
    这是一个创建于 387 天前的主题,其中的信息可能已经有所发展或是发生改变。
    - Root
      - router1
        - category1
            - interface1
              - prefix1
              - prefix2
            - interface2
              - prefix21
        - category2
      - router2
        - category21
    

    上面是结构. api 的设计

    1. */api/routers/<router_id>/interfaces
    2. */api/interfaces/?router-id=<id> 哪种更好?

    如果下一层

    1. */api/routers/<router_id>/interfaces/<interface_id>/prefixes
    2. */api/prefixes?router_id=1&interface_id=2

    谢谢.

    13 条回复    2023-12-10 20:20:35 +08:00
    dif
        1
    dif  
       2023-12-08 14:08:08 +08:00   ❤️ 1
    一般会把参数放在路径里。所以,第一种好一点。下一层也是参数放在路径里。
    iosyyy
        2
    iosyyy  
       2023-12-08 14:12:17 +08:00   ❤️ 1
    如果有多个建议 2 只有一个建议 1 具体参考 V2EX github 等的设计
    Pil0tXia
        3
    Pil0tXia  
       2023-12-08 14:16:44 +08:00   ❤️ 2
    router_id 作为一种资源,出现在路径中或参数中都是符合 RESTful API 的设计规范的。

    很多公司会选择同时支持两种用法;你也可以问一问前端同学的喜好,规范一种用法。

    通常国外的开发者会倾向于把资源放在路径中,国内的开发者会倾向于把资源放在参数中。这是两种不同的理念,如果这个接口日后的开发迭代会经常变动函数签名,那么把资源放在参数中可能更方便;如果你的资源只有有限的几种,那么把资源放在路径中更合理。
    error451
        4
    error451  
       2023-12-08 14:18:40 +08:00   ❤️ 2
    按照 restful 规范,很显然是第一种. 参数拼接很显然是不符合的。

    当然,实际中,第二种写起来要更灵活一些,你可以随意拼接任何参数。

    但是规范的目的本来就不是为了方便,规范是为了统一,让 URL 看起来更加清晰,避免歧义。

    比如说,在大家都熟知规范的情况下,你给我*/api/routers/<router_id>/interfaces , 我不需要查文档就明白,这肯定是一个 interfaces 的列表
    并且, 我想获取某个 routers 很显然就是*/api/routers/<router_id>, 我想获取 routers 的列表就是*/api/routers

    但是你要给我 */api/interfaces/?router-id=<id> , 我完全不知道该如何获取 routers 的列表和单个 routers 。

    这就是规范的意义,大家都遵守就减少沟通成本。

    最后,restful 按理说不要出现复数, 资源写成 router ,interface 就可以了
    hronro
        5
    hronro  
       2023-12-08 14:40:20 +08:00   ❤️ 1
    @error451 说错了吧,Restful 中应该尽量用复数
    lonelee
        6
    lonelee  
       2023-12-08 14:57:51 +08:00   ❤️ 1
    作为前端的同学,我更喜欢第一种,第二种如果是 get 请求容易跟参数混在一起
    sx931210
        7
    sx931210  
       2023-12-08 15:04:31 +08:00   ❤️ 1
    严格遵守 restful 你不难受谁难受,完全没必要
    shenjinpeng
        8
    shenjinpeng  
       2023-12-08 15:08:29 +08:00   ❤️ 1
    可以这样

    /api/routers/<router_id>/interfaces

    /api/interfaces/<interface_id>/prefixes
    xiangyuecn
        9
    xiangyuecn  
       2023-12-08 16:25:43 +08:00   ❤️ 1
    屎山代码:*/api/routers/<router_id>/interfaces

    易于封装:*/api/interfaces/?router-id=<id>
    OilMoe
        10
    OilMoe  
       2023-12-09 23:08:47 +08:00
    这很不国内,不应该是全部 POST + get.* 起手吗
    veike
        11
    veike  
       2023-12-10 04:16:39 +08:00 via Android
    面向资源设计的 API 资源 ID 肯定放在路径参数中,而不是 query 里
    fancy2020
        12
    fancy2020  
       2023-12-10 12:49:49 +08:00
    我觉得取决于,两种资源之间的逻辑关系,是不是一定是父子的关系。
    比如,interfaces 有没有可能独立于 routers 存在? prefixes 有没有可能独立于 interfaces 存在?

    如果答案是,interfaces 是一定会依附在一个 router 上,那么放在 path 里会更好。
    如果答案是 interfaces 可以不依附于一个 router ,那么只能放在 query 里。
    如果答案是不一定,未来有可能更改,那么放在 query 里会更灵活。
    mingwiki
        13
    mingwiki  
       2023-12-10 20:20:35 +08:00
    不要老是用后端思维,基本的 server rewrite 功能也用上。我觉得一个应用服务一个 api 路由就够了,不同服务让 nginx 、caddy 之类的 rewrite 。
    建议用这个 routers<router_id>/api/interfaces
    针对不同的服务 rewrite /api/ routers<router_id>/api/
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2570 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 07:15 · PVG 15:15 · LAX 23:15 · JFK 02:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.