API 设计规范问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Jakesoft
V2EX    问与答

API 设计规范问题

  •  
  •   Jakesoft 2016 年 11 月 18 日 3162 次点击
    这是一个创建于 3373 天前的主题,其中的信息可能已经有所发展或是发生改变。

    获取某个用户发布的文章:

    api/v1/user/{userId}/posts

    还是

    api/v1/user/posts/{userId}

    还是

    api/v1/user/posts?userId={userId}

    呢?

    18 条回复    2016-11-21 10:29:39 +08:00
    Geebarwan
        1
    Geebarwan  
       2016 年 11 月 18 日 via iPhone
    第一种
    wayn3h0
        2
    wayn3h0  
       2016 年 11 月 18 日
    RESTful:
    GET api/v1/users/{uid}/posts
    mhycy
        3
    mhycy  
       2016 年 11 月 18 日
    从客户端合成 URI 的角度来看
    2>3>1

    从扩展能力看
    2>1>3
    1 、 2 都能添加 get 形式后缀, 3 的 GET 形式后缀会与必要的 userid 冲突

    从 URI 路由效率来看
    3>2>1

    综上所述,选择 2
    murmur
        4
    murmur  
       2016 年 11 月 18 日
    我选择第三个,这个链接我闭着眼睛都能扩展为
    api/v1/user/posts?userId={userId}&pageSize=20&page=5&search=java
    用 restful 的你们继续想吧
    restful 如果能做到的, query param+nginx rewrite 就可以轻松做到
    反之可未必
    huijiewei
        5
    huijiewei  
       2016 年 11 月 18 日
    避免层级过深的 URI

    /在 url 中表达层级,用于按实体关联关系进行对象导航,一般根据 id 导航。

    过深的导航容易导致 url 膨胀,不易维护,如 GET /zoos/1/areas/3/animals/4 ,尽量使用查询参数代替路径中的实体导航,如 GET /animals?zoo=1&area=3
    elvba
        6
    elvba  
       2016 年 11 月 18 日   2
    我选择 api/v1/users/{userId}/posts

    以及说用 restful 就不是用 ?fidle=value&search=value 的意思,查询参数可以对获取的资源再进行过滤

    api/v1/user/posts?userId={userId}&pageSize=20&page=5&search=java 然而这也是 resful 风格…… 获取所有用户的文章,再用查询参数进行过滤

    参考:
    http://www.vinaysahni.com/bst-practices-for-a-pragmatic-restful-api
    lrh3321
        7
    lrh3321  
       2016 年 11 月 18 日
    我选 第一种

    截 api/v1/user/{userId} 出来,很容易就找到了发文章的用户
    jerray
        8
    jerray  
       2016 年 11 月 18 日
    支持 #6 选 1
    wupher
        9
    wupher  
       2016 年 11 月 18 日
    支持第一种,但是如果是长期项目,不赞成版本号放到 URL 上。
    mornlight
        10
    mornlight  
       2016 年 11 月 18 日
    我倾向第一种, post 和 user 有明显的归属关系
    baiyi
        11
    baiyi  
       2016 年 11 月 18 日
    第一种 支持 #6 的看法
    keepcleargas
        12
    keepcleargas  
       2016 年 11 月 18 日
    第一种. 实际使用中 也是.
    wesley
        13
    wesley  
       2016 年 11 月 18 日
    用 api/v1/posts?userId={userId}
    这样只提供一个接口
    否则的话,返回某人的 post 要做一个接口, 返回某喵的 post 又要一个接口,返回某汪的 post 又又要一个接口
    mhycy
        14
    mhycy  
       2016 年 11 月 18 日
    @wupher
    恰好是长期项目才需要把 API 的版本号写在 uri 上面
    这样能保证以后新 API 更新的时候老 API 不用做任何改变
    新特性使用新版本号就好了
    learnshare
        15
    learnshare  
       2016 年 11 月 18 日
    RESTful

    user/{userId}/post

    不是 posts
    wupher
        16
    wupher  
       2016 年 11 月 21 日
    @mhycy 这个问题,你可以参考:
    Jakesoft
        18
    Jakesoft  
    OP
       2016 年 11 月 21 日
    综合楼上各位的观点,发现我提到的三点几乎每一个都有不少人支持或者在使用,当然大家都有自己的理解,我有时候也很困惑该使用哪种 api 风格,是否有必要严格遵守 REST 呢?我也发散一下我的浅见吧,如有不妥请多读包涵

    对于一个获取订单的 api ,我们自然联想到使用 GET 请求,但是这个获取起始后台做了很多事情,比如:

    1.通知卖家有人查看了你的商品
    2.在`我的历史查看`做记录
    3.在`哪些人最近查看了该商品`做记录
    ...

    这似乎就是一个 “我把我的信息给你,你做一下这些(上述)操作,完了把我要的东西给我”的请求

    那这还是一个纯粹的 GET 请求吗?

    REST 似乎强调 header 以及 http code 的重要性,但实际上:
    1.header 不能随意添加, client 可能不识别不安全的 header,并且我们不能直观的从 url 上得到确切的 api 信息,往往还需要看 header 。
    2.http code 难以记忆,并且业务复杂的系统还是需要业务 code 来处理,所以除了 200 , 400 , 500 这些常用的 code 之外,其余的似乎并不能更好的让你开发 api
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1852 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 52ms UTC 16:12 PVG 00:12 LAX 08:12 JFK 11:12
    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