这样的api设计合适么

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

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

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

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

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

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

你可以看看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
2013-07-29 10:24:12 +08:00
其实在其他业务的列表页面,所需要的用户信息不多,很多情况可能就是一些最基本的用户名什么的,这个可以在列表接口给出,但是详细的信息必须是新接口,这样设计感觉更合理一些。
tt0411
2013-07-29 11:37:02 +08:00
@BB9z

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

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

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

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

我的架构方式一般是

手机app
webapp
后端api

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

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

但你这个具体问题倒不是很合适了,你请求的时候又不知道user id。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/77261

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX