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

有关 Restful API 的疑问

  •  
  •   bdbai
    bdbai 2015-09-03 08:39:33 +08:00 via iPhone 5293 次点击
    这是一个创建于 3745 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比如说有个获取帖子的 API ,应不应该把发布者的用户名、头像地址一起传回?还是只留个用户 ID 即可?
    33 条回复    2015-09-05 23:15:35 +08:00
    ljbha007
        1
    ljbha007  
       2015-09-03 08:50:56 +08:00
    一般要一起回传 节约流量
    dofaith09
        2
    dofaith09  
       2015-09-03 08:58:03 +08:00
    尽量在一次请求完成, 多次请求网络延时比较大
    minbaby
        3
    minbaby  
       2015-09-03 09:18:18 +08:00 via iPhone
    一般来讲,从逻辑上区分而不是从节省流量和时间上区分,逻辑上讲这些是有直接关联的所以更适合放在一起,如果处于其他考虑分开也是可以接受的
    gevin
        4
    gevin  
       2015-09-03 09:21:12 +08:00
    同意楼上,逻辑合理是第一位的
    bdbai
        5
    bdbai  
    OP
       2015-09-03 09:24:04 +08:00 via iPhone   1
    @ljbha007 为什么一起回传会节约?如果用户信息会缓存呢?
    @minbaby @zyx89513 那么就一起传回咯
    ljbha007
        6
    ljbha007  
       2015-09-03 09:29:01 +08:00
    @bdbai
    HTTP 请求头有开销呀
    还有多次请求对服务器的压力也会更大一些 同时加载速度也会有影响
    loading
    &bsp;   7
    loading  
       2015-09-03 09:41:48 +08:00 via iPhone
    如果不一次传回,你下一步不就要获取这些信息了?
    回帖必然要带用户信息吧,不然你后续如何区分?所以就一起回传了。


    你应该不会是指用户的头像数据吧?你要压成 base64 传?传个地址就行,这样浏览器才能使用缓存!
    learnshare
        8
    learnshare  
       2015-09-03 09:42:26 +08:00
    客户端用的话,一般要一次传回相关数据,否则让客户端多次查询,是很慢的。
    loading
        9
    loading  
       2015-09-03 09:43:54 +08:00 via iPhone
    如果你直流 id 号,你可以试下在这个 api ,每个 id 请求一次,顺便也能做个压力测试了…看你服务器能不能挡住,每个帖子 10 个回复,也就 10 个请求而已…
    bdbai
        10
    bdbai  
    OP
       2015-09-03 10:45:49 +08:00 via iPhone
    @ljbha007 其实加载倒问题不大 各种动画能糊弄一下
    @loading 主要是考虑到客户端缓存可以灵活一点 头像当然是地址咯
    @loading 我不会说我用 SAE 的
    iyangyuan
        11
    iyangyuan  
       2015-09-03 11:55:25 +08:00 via iPhone
    这得看具体需求,如果盲目一次传回,不仅会造成业务逻辑上的耦合,而且造成资源浪费,又违反按需加载的思想。但如果有接下来必须用到的关联数据,那就没必要分多次请求了。
    loading
        12
    loading  
       2015-09-03 11:58:31 +08:00 via iPhone
    如果你是全端,那你还不合格才会问这个问题!
    如果你是后端,问下你前端人员的意见!
    qiayue
        13
    qiayue  
    PRO
       2015-09-03 12:11:46 +08:00 via Android
    需要什么就传回什么,比如帖子里需要显示发帖者的昵称头像,那么就只返回用户的这两个数据,用户的其他数据就没必要返回了
    jeansfish
        14
    jeansfish  
       2015-09-03 12:14:57 +08:00
    缓存就让客户端去判断, api 给出来就行了
    bdbai
        15
    bdbai  
    OP
       2015-09-03 12:56:29 +08:00 via iPhone
    @iyangyuan @qiayue @jeansfish 明白了
    @loading 虽然只是后端,不过经验严重缺乏。还请多指教。
    msg7086
        16
    msg7086  
       2015-09-04 04:27:16 +08:00   1
    @loading 每个 ID 请求一次?这是什么新鲜的逻辑?是不是 SQL 也只能一次请求和返回一条数据了?

    @bdbai 具体怎么做要看具体情况的。
    比如说你前端程序是不是 SPA ,如果是的话, SPA 内部可以缓存数据,每次只要返回差值即可。
    多次请求也就现在开销大点,然而现在的 SPDY 和以后的 HTTP/2 都会压缩报头和流复用,多个请求回复和单个合并的请求回复并不会有想象当中的那么大。

    另外,像你这个返回帖子数据的 API ,根本不用等用户数据下载完就可以显示帖子了。等用户数据下载完了再把更新后的数据写入页面即可。

    不过呢,如果你在创业公司的话,还是怎么简单怎么来,只要后端做好模块化,易于拆分的话,就算是合并输出也无所谓。毕竟初期快速迭代出产品比什么都重要。
    loading
        17
    loading  
       2015-09-04 06:27:11 +08:00 via iPhone
    @msg7086 希望你看清楚一点,我是说一个不合理的 api 设置造成的问题。
    bdbai
        18
    bdbai  
    OP
       2015-09-04 08:31:13 +08:00 via iPhone
    @msg7086 loading 说的是单独请求用户信息对服务器的压力...
    确实是 SPA ,还有手机 app 。因为是在 SAE 上的,所以 SPDY 和 HTTP/2 可能比较麻烦。等以后移植了再说。
    多谢指点。
    msg7086
        19
    msg7086  
       2015-09-04 08:47:39 +08:00
    @loading 看了半天没看明白你什么意思。
    1 个帖子 10 个回复, 10 个 id 拿用户数据也就 1 个请求就足够了,为何要去测什么 10 个请求。
    bdbai
        20
    bdbai  
    OP
       2015-09-04 10:31:22 +08:00 via iPhone
    @msg7086 你说的是"批量获取用户信息"?
    msg7086
        21
    msg7086  
       2015-09-04 10:35:34 +08:00
    @bdbai 是啊。这就是典型的 N+1 问题优化。 1 个请求+N 个子请求,优化成 1+1 一共 2 个请求。
    atom
        22
    atom  
       2015-09-04 11:02:24 +08:00
    孤立看问题的撕逼钓鱼贴 :)
    response 的 size 不是过大的时候,一次请求“就近”返回信息,减少连接数,效果是很客观的。
    没做过 APP ,单纯从桌面浏览器来看,连接数过多页面加载的效果非常差,而且 js 的调度,一般认为是个单线程的东西。
    loading
        23
    loading  
       2015-09-04 11:03:00 +08:00 via iPhone
    @msg7086 其实你看懂了,我为了说明楼主这个只传 id 的缺陷,就按没合并的情况下说的。

    楼主这个就是先给 id 然后又至少根据 id 查一次的情况,这个明显就应该合并!
    bdbai
        24
    bdbai  
    OP
       2015-09-04 13:27:05 +08:00 via iPhone
    @msg7086 @loading 好的好的 合并合并:)
    @atom 本无意钓鱼...
    msg7086
        25
    msg7086  
       2015-09-04 13:33:03 +08:00
    @loading
    @bdbai
    我反正觉得应该分开。
    loading
        26
    loading  
       2015-09-04 13:59:31 +08:00 via iPhone
    @msg7086 我发出以上内容的出发点是:楼主说的 id ,我理解是 id 号~因为我看到楼主还说了用户名这个东西,所以我就单纯地理解为 id 是个数字,也就是我们说的 uid
    loading
        27
    loading  
       2015-09-04 14:04:05 +08:00 via iPhone
    @loading 因为我觉得应该不会给用户一个数字,必须要把它变成用户名,如果只是这个问题,我的观点就是合并,在 sql 时就是一个 join 的问题,毕竟如果不返回,马上就必须来个请求找用户名了。

    这是我回答这个问题的过程。


    也许跑偏了太多~
    msg7086
        28
    msg7086  
       2015-09-05 02:26:18 +08:00
    @loading 所以我觉得应该分开,让 API 做到单一职责。

    以前用 PHP 的时候,习惯于大量用 SQL 语句做 JOIN ,因为这样方便,一句话返回所有我要的数据就行了。
    这种情况下自然就产生出你说的这种输出方式,用 JOIN 把用户数据一起加载进帖子数据里。

    现在用 RoR , ActiveRecord 倾向于分开查询,就是第一次先查帖子数据,然后用拿到的用户 ID 去做第二次查询。好处是查询更容易被缓存,以及表结构更容易做性能优化。(毕竟索引只要建在主键 /外键上就好了)这样就自然而然出现了两次查询的做法,即:

    get_json (:posts )
    .then {
    - display_posts
    - find_user_ids
    - return get_json (:users, user_ids )
    }.then {
    - replace_user_info_by_id
    }
    luago
        29
    luago  
       2015-09-05 10:36:32 +08:00
    建议回传,客户端如果已经缓存了头像,你的传输成本只是增加了用户名和头像地址的字符串长度而已。
    railgun
        30
    railgun  
       2015-09-05 12:01:12 +08:00
    加个开关,让客户端自己判断就好了
    bdbai
        31
    bdbai  
    OP
       2015-09-05 14:26:20 +08:00 via iPhone
    @luago 积少成多 另外客户端还能缓存用户信息呢
    @msg7086 隐约感觉外部可以全都传 系统里面还得抽象
    vela
        32
    vela  
       2015-09-05 19:12:57 +08:00
    个人倾向于接口设计成原子性的,减少接口设计和视图耦合后造成的接口数量爆炸或者维护成本陡增。至于减少请求次数或者减少 RTT 开销,可以交给底层做。比如吧,直接上 http/2 。
    至于楼主问的索引和实体数据要不要一起返回,如果架构设计允许,分开返回可以设计成客户端本地缓存部分数据,减少下行量(增加的一次请求开销在 http/2 或者 spdy3.1 下不会太多)。但是设计不好很容易增加复杂度和 bug 率或者响应时间陡增之类的,所以没啥时间简单做就一起返回啦。
    zhangv
        33
    zhangv  
       2015-09-05 23:15:35 +08:00
    RESTful 是 API 的设计约定,说的简单点就是你设计一个 function 的参数和返回值是什么样子的。 --- 这些首先取决于你的需求(也就是使用这个 function 的人),而不应该是首先考虑是否应该减少内存使用。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     955 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 19:33 PVG 03:33 LAX 11:33 JFK 14:33
    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