V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tt0411
V2EX  ›  程序员

这样的api设计合适么

  •  
  •   tt0411 · 2013-07-28 22:18:08 +08:00 · 4580 次点击
    这是一个创建于 4120 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近开始帮人做一个安卓app,服务器的api是另一个人写的。开始看api时,发现一个问题,就是比如请求一个items列表,每个item中有一个关联的user,但是从返回的json来看,关于这个user只有一个userid。我就问web端(像个SPA应用)的同事要显示user的其他属性咋办,他的回答竟然是根据每个userid请求另一个有完整信息的api。当时我就震惊了,web版看样子应该做了至少一个月了,这个问题就是一直这么解决的?回答说,api那边说先这么用。当然这些不是提问的重点。

    我和负责api 的人(兼职的,其实我也算兼职)交流了,他勉强认同了这么做不合适,而他给出的解决方案是提供另一个api接口,这个接口接受现有的几个api的地址和参数的组合合并(就是发送一个包含api地址和参数的数组),发送为一个api请求,从而减少请求数。他的理由是这样的合并方式比较灵活,api这边需要维护的接口不会太多。我没怎么写过服务器端的api,却也用过一些,总感觉这样做不合适,而又说不清楚,同时又是人微言轻。我想问下有人做过类似的设计么?这种设计(api组合)合适么?
    23 条回复    1970-01-01 08:00:00 +08:00
    cxe2v
        1
    cxe2v  
       2013-07-28 22:39:10 +08:00
    明显不合适!
    victor
        2
    victor  
       2013-07-28 22:49:25 +08:00
    @cxe2v 那你说怎么样合适?
    123123
        3
    123123  
       2013-07-28 22:49:53 +08:00
    这肯定要改,直接在原接口上附加上user属性,下次手机端版本要去改代码
    xing393939
        4
    xing393939  
       2013-07-28 23:23:55 +08:00 via Android
    应该返回2个结果集,一个是item的,一个是userid对应用户信息的关联数组,里面是items用到的用户信息
    vigoss
        5
    vigoss  
       2013-07-29 00:48:17 +08:00
    不合适啊,手机端尽量少调用一次API就少掉一次呗..又不是web里的逻辑代码.或者是数据库设计,还灵活..

    灵活也是把接口做灵活,以后升级可以直接加新参数,代码不需要改动太多.
    tt0411
        6
    tt0411  
    OP
       2013-07-29 07:39:08 +08:00
    我主要想问的是,有没有这种 api组合式 的设计?

    我听说,淘宝上有一种css(和js)文件合并的机制,比如链接 host/?param=file1.css+file2.css,会合并两个css为一个css返回。当然这些文件主要是资源文件。api设计上,是否有公司做过类似的尝试?
    refresh
        7
    refresh  
       2013-07-29 08:06:33 +08:00 via iPad
    你获取微博难道还带有用户信息?
    cevincheung
        8
    cevincheung  
       2013-07-29 08:49:36 +08:00
    @refresh 还真是。获取微博带有用户信息。http://open.weibo.com/wiki/2/statuses/public_timeline
    Paranoid
        9
    Paranoid  
       2013-07-29 08:54:36 +08:00
    我们这边手机端给的需求API 只要有关联对象给的都是对象的详细信息, 详细信息里面还有对象? 继续给, 看需求决定.

    多次请求显然是不合适的.
    BB9z
        10
    BB9z  
       2013-07-29 09:19:51 +08:00
    多个请求组合成一起的有这么做的,能改善 2G 网络下的表现。

    不过个人很不喜欢这种做法,太不 RESTful 了。
    jjx
        11
    jjx  
       2013-07-29 09:47:14 +08:00   ❤️ 1
    其实,没有设计是一步到位的,指责设计不当感觉不适合,

    你可以看看restful 最佳实践,可以让他增加一个embed(或者expend) 参数

    自动加载相关的资源

    很多时候,自动加载相关资源非常有用,可以很大的提高效率。但是这却和RESTful的原则相背。为了如此,我们可以在url中添加参数:embed(或者expend)。embed可以是一个逗号分隔的串,例如:

    1
    GET /ticket/12embed=customer.name,assigned_user
    对应的API返回值如下:


    {
    "id" : 12,
    "subject" : "I have a question!",
    "summary" : "Hi, ....",
    "customer" : {
    "name" : "Bob"
    },
    assigned_user: {
    "id" : 42,
    "name" : "Jim",
    }
    }
    值得提醒的是,这个功能有时候会很复杂,并且可能导致N+1 SELECT 问题。
    http://blog.jobbole.com/41233/
    ququzone
        12
    ququzone  
       2013-07-29 10:24:12 +08:00
    其实在其他业务的列表页面,所需要的用户信息不多,很多情况可能就是一些最基本的用户名什么的,这个可以在列表接口给出,但是详细的信息必须是新接口,这样设计感觉更合理一些。
    tt0411
        13
    tt0411  
    OP
       2013-07-29 11:37:02 +08:00
    @BB9z

    > 多个请求组合成一起的有这么做的,能改善 2G 网络下的表现

    请问能给出具体的链接信息么
    tt0411
        14
    tt0411  
    OP
       2013-07-29 11:38:07 +08:00
    @jjx 嗯,我去看看
    dorentus
        15
    dorentus  
       2013-07-29 11:47:57 +08:00   ❤️ 1
    其实后端想偷懒的话,正确的方式我觉得应该是按楼主需要的方式提供一个或多个新接口,这个接口在内部使用一个代理服务『接受现有的几个api的地址和参数的组合合并』发送给真正的后端服务,这样吧。

    目前楼主所说的后端的新解决方案,是灵活了,但那是用户(也就是楼主这里的API调用者)完全不需要的灵活性,反而增加了理解的难度,也限制了以后后端架构更新的灵活性。

    我上面说的那个实现方法,对API调用者来说完全是个黑盒,之后后端可以随时按自己的节奏来修改甚至重新实现。这才是真正的灵活。
    sivacohan
        16
    sivacohan  
       2013-07-29 13:50:39 +08:00
    听你说的,好像是整个架构少了一层啊……

    我的架构方式一般是

    手机app
    webapp
    后端api

    你说的这种架构好像是没写webapp,直接把后端api暴露给手机app了。
    我觉得手机用的api需要经过webapp重新封装一下。
    tt0411
        17
    tt0411  
    OP
       2013-07-29 13:54:25 +08:00
    @sivacohan webapp指的是?如果是浏览器应用的话,是有webapp的。api用的是ruby的grape写的,ruby不熟悉,所以具体实现不清楚。
    lightory
        18
    lightory  
       2013-07-29 14:10:59 +08:00   ❤️ 1
    我觉得这样的做法是合理的。在业务持续变动的情况下,能够保证 API 很好的可维护性。

    但如果确定业务后面不会有大的调整,那还是采用嵌套资源吧。
    meta
        19
    meta  
       2013-07-29 14:13:48 +08:00
    这个只有权衡了,可以带点user的关键信息,要是每个item都带user的完整信息,那流量怕是要暴涨。
    tshwangq
        20
    tshwangq  
       2013-07-29 16:20:26 +08:00   ❤️ 1
    组合请求是一个比较好的概念。
    你看facebook 的api都支持 batch request.

    但你这个具体问题倒不是很合适了,你请求的时候又不知道user id。
    tt0411
        21
    tt0411  
    OP
       2013-07-29 20:02:14 +08:00
    @lightory
    @tshwangq

    batch request是个不错的概念,学习了。但是感觉会增加客户端编程的复杂性。同时我更认同 @dorentus 的观点,api应该“黑盒”,不能暴露内部细节。
    lightory
        22
    lightory  
       2013-07-30 00:48:24 +08:00
    @tt0411 @dorentus

    我觉得还是要看 API 是公开给外部开发者,还是仅供内部开发者使用。我猜 @tt0411 的情况是后者。

    那么:

    1. 内部使用的 API,往往后续需求变动的可能性比较大。如果对于每个需求都新增 API(或在现有 API 增加字段),维护成本会异常大,将每个 API 拆分到足够小的粒度是比较好的做法。这么做也有其它一些额外的好处,譬如简化缓存的实现。

    2. 内部开发者应当对数据模型及关系有清晰的认识,黑盒不黑盒不是太大的问题。

    另外,关于客户端的复杂度。如果服务端做 batch request,客户端应该也有相应的封装。
    GTim
        23
    GTim  
       2013-07-30 07:46:41 +08:00
    参考新浪微博的use返回方式,不错的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3513 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 04:30 · PVG 12:30 · LAX 20:30 · JFK 23:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.