关于 RESTful 风格的 url 设计疑问 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
JavaFirstMaster
V2EX    问与答

关于 RESTful 风格的 url 设计疑问

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

    目前 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     Solana     5710 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 03:00 PVG 11:00 LAX 19:00 JFK 22:00
    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