V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
JavaFirstMaster
V2EX  ›  问与答

关于 RESTful 风格的 url 设计疑问

  •  
  •   JavaFirstMaster · 2017-10-31 16:08:39 +08:00 · 3513 次点击
    这是一个创建于 2614 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前 RESTful 风格的接口设计越来越流行.我公司用 vue+nodejs 做的单页面应用也一直践行这种风格,但是总觉得 url 设计好奇怪.

    举个栗子:一个"项目(project)"下包含很多"店铺(shop)",店铺下面又包含很多"商品(product)",这样一来:

    • 查看 id 为 2333 的项目页面 URL 被设计为 /project/2333
    • 查看此项目下 id 为 4567 的店铺页面 URL 被设计为 /project/2333/shop/4567
    • 查看此店铺下 id 为 9999 的商品页面 URL 被设计为 /project/2333/shop/4567/product/9999

    这只是个例子,实际项目中 URL 被搞的特别长.这样设计有一个原因是这些 id 用来传参(vue 中的 route 相关),难道没有更优雅的解决方案吗?

    11 条回复    2017-11-01 23:18:50 +08:00
    coderfox
        1
    coderfox  
       2017-10-31 16:23:40 +08:00 via Android
    你可以把 project, shop, product 的 id 都搞成全局唯一的。
    laxenade
        2
    laxenade  
       2017-10-31 16:24:07 +08:00 via Android   ❤️ 1
    感觉挺符合 Restful 的 best practices
    feiyuanqiu
        3
    feiyuanqiu  
       2017-10-31 16:46:24 +08:00
    推荐的资源嵌套层级是两层
    层级太多的时候,首先需要考虑下设计是否合理,是否有必要将资源的依赖关系暴露出来,这种资源间的依赖关系对 api 的使用者来说真的是必要的吗?
    这个文档讲得比较详细: https://github.com/livingsocial/api-design#shorten-associations-in-the-uri---hide-dependencies-in-the-parameter-list

    另外,资源应该用复数:/projects/233/shops/233, /shops/233/products/233
    justfindu
        4
    justfindu  
       2017-10-31 16:49:21 +08:00
    所以
    我不能单独使用 shop/4567 访问 shop ?
    我不能单独使用 product/9999 访问 product ?
    我只能先找 project 再找 shop 再找 product ?

    所以是不是你设计有问题咯
    sunjourney
        5
    sunjourney  
       2017-10-31 18:14:03 +08:00
    应该这么用啊:
    projects/xxx
    shops/xxx
    products/xxx

    属于 project 的 field 才嵌套
    Kilerd
        6
    Kilerd  
       2017-10-31 18:21:55 +08:00
    @sunjourney 这就是你的理解不透彻了

    一般来说,有独立索引的才会提出单独的来

    比如对于用户地址来说一般就是 /user/addresses 而不是单独用 /addresses 因为他依赖于 user 这个资源

    而对于用户发表的文章,推荐用 /articles/<id> ,同时 /user/articles/<id> 也可以做指向
    JavaFirstMaster
        7
    JavaFirstMaster  
    OP
       2017-11-01 08:48:15 +08:00
    @coderfox 数据库用的 mysql,多张表之间保证主键的唯一性实现起来不好搞啊
    JavaFirstMaster
        8
    JavaFirstMaster  
    OP
       2017-11-01 08:49:09 +08:00
    @feiyuanqiu 蟹蟹,我去看看
    JavaFirstMaster
        9
    JavaFirstMaster  
    OP
       2017-11-01 08:51:15 +08:00
    @justfindu 我个人是觉得你讲的"/shop/233"来访问 shop 比较优雅,但是搞前端的说是方便 vue 单页面项目中传参方便,面包屑导航方便巴拉巴拉的,所以我觉得肯定有其他解决方案
    JavaFirstMaster
        10
    JavaFirstMaster  
    OP
       2017-11-01 08:56:06 +08:00
    @sunjourney
    @Kilerd
    对于我这边具体的项目来讲,你们说的不冲突,我们项目中确实对于 shop,product 等有单独索引,逻辑上有归属关系,通过数据库表中的一个字段(类似外键)来表示关系
    sunjourney
        11
    sunjourney  
       2017-11-01 23:18:50 +08:00
    @Kilerd #6 这是 api,不是视图 url,数据层也肯定是为 project、shop、product 单独建的 table/collection,当然就是用我方法请求。我说了,属于 project 的 field 才嵌套,如果 shops 放到了 project 的数据中,products 放到 shop 的数据中,是 project 文档的一部分,那建议嵌套成 projects/xxx/shops/yyy,反之不建议。你举 article 的例子,前端视图上是 users/xxx/articles/yyyy 可以,但如果 user 和 articles 分开,api 用 articles?authorid=yyyy 更宜,服务端也方便。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2804 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 07:12 · PVG 15:12 · LAX 23:12 · JFK 02:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.