关于 REST API 设计,我的看法

2015-03-17 11:49:05 +08:00
 yueyoum
如果是设计公共API,你给其他人提供服务,那么老老实实按照规范来,
因为规范就是统一的认知,也不会给别人带来多少困扰。

但如果是自家产品,我的经验就是不要REST了, 所有请求统统POST
参数加密后放入 request body 中

http://wtser.com/2015/03/08/who-cares-about-get-vs-post-norest.html

这篇文章 与我现在的观点一致。


除了文章中所说的,我再说几点好处:

1, 更方便的自动生成代码。
不用区分是GET,POST,DELETE 这些。客户端自动生成代码将极度简化。

2, 数据加密。
上面已经说了, 数据在 post body中,是加密的。
至少不去研究,直接抓包看不出什么。

3, 更方便的服务器安全控制。
自己的API都是POST,可能有一些与第三方厂商对接的接口是GET,
那么只要在nginx中 将第三方GET接口 设置为 可以GET访问
其他接口全部 要 POST 访问,非POST统统deny

4, 更明确的错误提示
客户端有一个输入框,输入其他用户ID (纯数字),可查看这个用户的信息
那么 REST API 就是 GET /userInfo/<ID>

URL ROUTE 配置应该是 <ID> 匹配纯数字 对不对? 这样才是明确的 REST API 啊
如果 用户输入有 汉字, 那么你返回 404呢?
还是返回200 但是 返回结果是这样的?

{
'ok': false,
'message': '用户ID只能是数字'
}

这个时候 客户端只要 判断返回的 ok 不为 true,直接弹框显示 message 即可。




总之我的经验就是全部POST,简单,方便,少写代码!
13236 次点击
所在节点    程序员
76 条回复
robertlyc
2015-03-17 13:31:46 +08:00
一派胡言
fengliu222
2015-03-17 13:32:02 +08:00
楼主追加的内容,让人觉得你对RESTful并不了解。
「一个人要给另个人100金币」的这种情况,RESTful的接口完全不是你所说的那样,正确的接口形式应该是:
POST /transaction
from=1&to=2&amount=100

发送的方式恰如你后面所说的。
关于RESTful架构,有一篇资料可供参考:
http://www.ruanyifeng.com/blog/2011/09/restful.html

文章里提到了几个误区,其中一个正是你所描述的。
yueyoum
2015-03-17 13:35:49 +08:00
@fengliu222

哈哈 首先先说头像的问题,

五年前的照片了, 你还是第一个对 这个照片 发表观点的人

首先 当时室内亮度很低,于是就开了闪光灯
其次 对着镜子自拍开 闪光灯 并不怪。
比如这张: http://7xi4k5.com1.z0.glb.clouddn.com/x.png


就是因为用了POST, 所以不用区分请求类型了。

可读性确实 标准REST 肯定很好,
但是我的做法就是 在URL上 写明功能
比如 /user/create/, /user/delete/
fengchang
2015-03-17 13:44:25 +08:00
v2ex上有些人,开口就是你先去读xxx。

其实楼主说的很明白了,不用RESTful就是把HTTP操作和状态码放进body里。虽然闲置了HTTP中的一些约定,但是也无不可。

前端的开发又不是傻子,GET /user他能看懂,/get_user他就看不懂,非要文档了?还是status 404他能看懂,"errcode":"404"他看不懂?

这和单后端又有什么关系,耽误你用android了还是耽误你用angularjs了?

设计过API的人都知道设计API的累,尤其是你费了好多心思,结果最后API就两个人用的时候。楼主的心情我懂
syv2
2015-03-17 13:44:48 +08:00
@yueyoum 你的想法和我多年前的想法类似,当时也觉得奇怪,无非就是告诉服务器自己要干什么嘛,搞这些什么restful什么抽象资源什么模型的,浪费那么多时间,有个鸡毛用。
然后眼睁睁看着自己掉到自己的大坑里。。
你说的对,keep it simple,你喜欢简单没错。可要知道最佳实践是无数前人总结出来的经验,不一定适合你,但是绝对适合大多数情况,你可以个性,但是这个行业里很多的约定俗成真的不是为了泯灭个性的,是真的为了提升生产率而存在的。
只能说,你写的代码还很少。
zhicheng
2015-03-17 13:46:23 +08:00
1,只使用 POST 这种方式设计接口,也有很多很多年了。。。。
同时用 GET,POST,PUT,DELETE 一样也容易生成代码,没有什么本质区别。

2,就是这个可以用任何加密才有意思。
如果你用对称加密,好,你要把密码放到客户端里。找到你用的密码只要 10 分钟。
如果你用非对称加密,虽然无法解密数据,但是,1如果服务器密钥泄露,所有数据全部泄露。2无法升级公钥加密强度。所以,不要太想当然放到 body 里就好加密了。这种接口加密只有一种办法,就是用 TLS !

3,这个安全控制。。。意义何在?
反而更不能精确控制,比如某些接口只出数据,只允许 GET 。有些只收数据通通 POST 。有些不允许 DELETE 就 deny 掉。

4,建议阅读一下 RFC 文档,非 HTTP 200 之类的返回,也可以带 body 。。。

对于协议这种东西,大多数人最容易犯的错误就是,我设计的会比 HTTP/TLS 更好。。。
yueyoum
2015-03-17 13:50:38 +08:00
@syv2

然后眼睁睁看着自己掉到自己的大坑里

我很好奇 到底什么坑?

因为我几个项目都过来了, 还没遇到坑。

请指点
yueyoum
2015-03-17 13:52:43 +08:00
@fengchang

感谢认同我的感受。

写过很多系统,写过很多API, 最后 我觉得我找到了一种 省心的方式,
但大家认为我在胡说。。。
kxxoling
2015-03-17 13:53:23 +08:00
题主的例子更适合用 RPC?
timonwong
2015-03-17 13:55:13 +08:00
确实并无不可(因为限定了非共有API),因为 RESTful 之前就有很多这样做的,在方便的 URL routing 出现之前,"action" 都是包到 body 里面去的。

我个人倒是有点洁癖,现在宁愿多撸代码也不愿意这样写了。
yueyoum
2015-03-17 13:56:10 +08:00
@zhicheng

你说的对, 我表示赞同

但是 我也说过一些了, 不是说 不能,而是为了简单。

比如 接口访问控制, 我自己的API, 只接受POST, 以后新添加API , web server 配置根本不用动。
但 如果把这些 控制 写入 web server 的配置中,比如 nginx

那么 以后每次 接口有变更,就可能要修改 nginx 配置。



虽然 更精确的控制, 但是工作量一下大了很多。


如果 你是在自己代码里控制,那当我上面没说
robertlyc
2015-03-17 13:57:52 +08:00
连http协议都不懂

也难怪 现在移动互联网那么火 大批"专业"开发人员 抄起袖子就开撸
反正鼻子底下就看到自己的嘴

要坑也是坑接口调用者 死道友不死贫道呗
yueyoum
2015-03-17 13:58:43 +08:00
@timonwong

不不, 我所说的 action 还是对应自己的 url


我曾经也愿意多写代码,后来越来越烂, 只要系统是正常工作的,
最快的速度让系统没BUG的上线, 轻松生活,快速挣钱才是 真道理
yueyoum
2015-03-17 14:03:39 +08:00
感谢各位

除了 @robertlyc 这个喷子 以外, 其他人都送出了感谢。

我的思想比较怪异吧, 技术论坛就是大家 畅所欲言 的地方, 这样才有新的收获。
就像我和我对象说,我并不怕我们吵架,因为生活中琐事太多,吵架也是一种发泄的方式。
虽然我会避免吵架。


我认识到 我还不懂 REST,
但我找到了合适做 个人/内部项目的 一种方式。

谢谢大家, 结帖
quix
2015-03-17 14:08:53 +08:00
@fengliu222 我觉得这种情况如果要保证幂等性应该是分两部, 第一步创建一个transaction_id, 第二步操作中附带这个 id, 如此才能真正保证一致性, 防止手抖一下连点两下啥的.
learnshare
2015-03-17 14:13:49 +08:00
要用 RESTful,就都用,要不就都不用。乱七八糟的接口最烦人。

@yueyoum
>“最快的速度让系统没BUG的上线, 轻松生活,快速挣钱才是 真道理”
这是欠揍的想法,追求完美不好么,非得写龌龊的代码给机器、给人看么!

来来来,一起学习 REST http://restcookbook.com/
crs0910
2015-03-17 14:15:12 +08:00
@Tr0y 请问你说的这种前后分离的工作形式,有什么开源的小项目可以参考下吗?求推荐。
otakustay
2015-03-17 14:15:46 +08:00
大部分人的误解在于,REST根本不是一种API风格,也不是一种URL风格,也不是一种实现模式。REST是一种设计方案,其重点在于次资源(Resource)作为第一层来进行设计,一切设计是面向资源及资源的状态转换。在这种设计的指导下,实现和API自然也会变成REST的,根本不会有其它更好的选择
所以其实很多人在做的是,用一种传统的设计思路,去硬套REST,觉得很不舒服,再回头来说REST各种不好……
laoyur
2015-03-17 14:25:54 +08:00
@zhicheng 26楼写得有理有据,赞一个
既然谈到加密用TLS,搭车问个https相关的问题,比如用charles等抓包工具进行https抓包,这些工具会中途替换证书(即中间人攻击),浏览器虽然会有警告,但还是能走得通;客户端就表现更差劲了,比如很多安卓应用(本人亲测),调用的https接口,有中间人攻击时一点反应都没有,charles抓包分分钟的事。

从这个意义上来说,是不是楼主说的“body部分非对称加密这种方式”,比TLS反而来得好?想听听您的评价,先谢个。
Tr0y
2015-03-17 14:30:51 +08:00
@crs0910 我们的项目没法开源,抱歉,不过这种开源项目整合成产品的好像很少,一般都是分别实现,例如很多框架都支持RESTful接口,移动端的类库也支持RESTful client的操作,AngularJS也有封装好的功能。
你可以看看github上类似的项目。
https://github.com/search?utf8=%E2%9C%93&q=restful&type=Repositories&ref=searchresults

我的框架实现了RESTful接口的服务端,里面的widget封装了js,来实现客户端的CRUD,有兴趣可以PM我。

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

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

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

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

© 2021 V2EX