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

关于 REST API 设计,我的看法

  •  
  •   yueyoum ·
    yueyoum · 2015-03-17 11:49:05 +08:00 · 13234 次点击
    这是一个创建于 3537 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如果是设计公共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,简单,方便,少写代码!
    第 1 条附言  ·  2015-03-17 13:17:32 +08:00
    似乎大家对 POST 数据加密 很感兴趣

    我帖子里没说清楚
    不是用了 POST 就自动加密, 好像我用了什么HTTP神功一样。

    而是不把参数暴露在 接口URL中, 也不作为 query string 放在 GET 参数中,

    而且 放入 POST BODY中, 这个要POST的东西, 可以是 form形式的,可以是 raw body形式的。
    然后对这个数据 可以用你们能用的任何方法加密处理一下。


    为了防止有人误解,还是举个例子吧

    一个人要给另个人100金币
    REST URL 是这样吗? POST /give/123/gold/100/
    给 123这个角色 100 金币


    你这API 是干什么的, 参数如何设置, 一眼就看出来了。


    你还可以这样:

    data = {'to':123, 'type': 'gold', 'value': 100}
    然后随你便,可以对data加密处理后, 再POST到 /give/ 这个接口
    第 2 条附言  ·  2015-03-17 13:48:18 +08:00
    最后一次 APPEND.

    看了大家的 观点后,

    我确实是不懂 REST,

    最近几个项目用了我自创的这种 万事POST的方式
    我自己觉是方便了, 于是就来说一下我的感受心得。

    总之,每个人都有每个人的方式吧。
    如果下个项目还是用 HTTP短链接交互,不用 sockets 长链接,
    我还是会用 现在的这种 万事 POST 大法。

    技术服务于人, 自己怎么方便怎么来。

    最后感谢大家参与讨论,每人送感谢!
    76 条回复    2015-03-20 19:46:18 +08:00
    maxiujun
        1
    maxiujun  
       2015-03-17 12:23:24 +08:00   ❤️ 1
    想知道一般如何加密post body?
    loading
        2
    loading  
       2015-03-17 12:25:12 +08:00   ❤️ 1
    公用 api 设计得再规范,没文档也不行,文档才是重中之重!
    zhicheng
        3
    zhicheng  
       2015-03-17 12:28:24 +08:00   ❤️ 1
    你的经验还太少。很多很多很多年前,接口都是这样设计的,一个URL处理所有的请求。
    我还有一个非常有趣的问题,如何对 body 加密?AES?Twofish?RSA?ECC?
    hbin
        4
    hbin  
       2015-03-17 12:37:25 +08:00   ❤️ 1
    不知道用 POST 之后,简单,方便,少写代码在哪
    syv2
        5
    syv2  
       2015-03-17 12:39:47 +08:00   ❤️ 1
    这是不把自家的前端当人看么
    yueyoum
        6
    yueyoum  
    OP
       2015-03-17 12:44:30 +08:00
    @zhicheng

    我没说一个URL啊, 每个功能还是自己的URL


    @hbin

    请仔细看贴


    @syv2

    用REST API, 写一大堆文档, 然后 客户端开发人员 对着文档自己写 代码。
    这里是 GET, url 是这样的, 这里是 POST, header 应该要加什么什么。

    累不累?


    我们只要用 配置文件写好简单的规则(xml, ini, ) 自动生成代码。 客户端就像在调用本地方法一样。


    对, REST风格的 一样可以 通过配置文件 自动生成代码,但是那个配置文件格式就复杂多了


    KEEP IT SIMPLE, STUPID
    pyKun
        7
    pyKun  
       2015-03-17 12:46:12 +08:00   ❤️ 2
    是有这个趋势,但全部post更适合于资源对象操作复杂的时候

    比如 aws ec2 管理虚拟机的 api 就是一个 api 对应一个 action
    pyKun
        8
    pyKun  
       2015-03-17 12:50:02 +08:00   ❤️ 1
    比较简单背景的需求,该是restful还是restful吧,楼主引用那个链接里的回复的那个人明显没见过特复杂的场景
    yueyoum
        9
    yueyoum  
    OP
       2015-03-17 12:51:00 +08:00
    @pyKun

    恩, 我的现在系统的设计也是 一个api 对应一个 action

    只不过不区分GET POST了, 全部POST
    yueyoum
        10
    yueyoum  
    OP
       2015-03-17 12:56:17 +08:00
    @pyKun

    我引用一下, 也是因为 看到有人和我一样的观点。

    就像 我并不会严格遵循 PEP8 一样, 比如一行不超过80字符。
    但有时候别人问我 代码为什么不PEP8, 我只能说 自己方便就行。
    你们也是 1080P 全屏IDE 写代码。

    但当我看 到 bottle 作者 https://github.com/defnull
    自己也说 PEP8 只是规范,不是强制要求, 所以bottle没有严格遵循。 的时候
    就会像找到知音一样,找到了观点相同的人。
    Catstyle
        11
    Catstyle  
       2015-03-17 13:03:29 +08:00   ❤️ 1
    自动生成客户端接口代码跟用什么method关系很大么...
    bkmi
        12
    bkmi  
       2015-03-17 13:07:47 +08:00   ❤️ 1
    我想问,为什么数据在post body里就是加密的?什么原理?另外用post,相比get简单方便代码少在哪里?
    yueyoum
        13
    yueyoum  
    OP
       2015-03-17 13:10:17 +08:00
    @Catstyle

    不大, 但 请不要钻牛角尖

    自动生成得有配置文件和规则, 也就是配置文件和生成规则的复杂度问题。

    简单有简单的做法
    复杂有复杂的做法


    我喜欢简单
    yuankui
        14
    yuankui  
       2015-03-17 13:11:57 +08:00   ❤️ 1
    内部使用,就用protobuf呗
    yueyoum
        15
    yueyoum  
    OP
       2015-03-17 13:18:43 +08:00
    @bkmi

    关于加密 见 append, 第二个问题 如果你有经验,自然会懂我帖子里的内容
    fengliu222
        16
    fengliu222  
       2015-03-17 13:18:54 +08:00   ❤️ 1
    REST的API,对于一个资源的操作,通过不同的请求类型来区分。
    用POST的话,应该还需要在URL或参数上进行区分吧,增加了沟通和记忆的成本。
    自动生成代码的部分不太懂,但对REST四种请求类型的封装,并非如你所说那么累,而且可读性更高一些。
    PS.对着镜子自拍的时候用闪光灯蛮怪的。。。
    yueyoum
        17
    yueyoum  
    OP
       2015-03-17 13:20:21 +08:00
    @yuankui

    是的, protobuf, msgpack, 这些库,都可以用。

    这也是我 把现在这个项目设计成 反REST 的原因。
    mkeith
        18
    mkeith  
       2015-03-17 13:24:26 +08:00   ❤️ 1
    Post请求比Get请求更耗时间吧
    Tr0y
        19
    Tr0y  
       2015-03-17 13:27:48 +08:00   ❤️ 3
    我觉得楼主根本没了解RESTful的实现,RESTful的接口实现的是数据操作上的幂等,用不同的request method,区分不同的操作,对于系统架构的优化和分层都有前置条件和基础,还有前端,移动端,其它平台(客户端) - 后端(服务端)能够实现完全分离,接口统一。

    至于接口文档方面大部分的业务根本不需要太详细的说明,只要有数据字典就可以基本描述完绝大多数业务,有需要特别功能接口的才需要单独写接口或文档,关联的业务可以在数据模型中处理。

    基于这样的实现,后端只需要开发一次。前端可以使用 angularjs 等框架,移动端是 android,ios。

    我们团队的后端基本上写完模型就完成了后端的开发。非常轻松,基本上就在那坐着等前端开发业务,在项目中成本差不多是2:8(后端两天能做完的事情,优秀的前端或者移动端差不多8天才能完成)

    建议楼主先熟读Roy Fielding的论文。
    adieu
        20
    adieu  
       2015-03-17 13:29:12 +08:00   ❤️ 1
    Google的这个库看起来貌似很厉害,如果要做内部api设计可以参考 http://www.grpc.io/
    robertlyc
        21
    robertlyc  
       2015-03-17 13:31:46 +08:00
    一派胡言
    fengliu222
        22
    fengliu222  
       2015-03-17 13:32:02 +08:00   ❤️ 4
    楼主追加的内容,让人觉得你对RESTful并不了解。
    「一个人要给另个人100金币」的这种情况,RESTful的接口完全不是你所说的那样,正确的接口形式应该是:
    POST /transaction
    from=1&to=2&amount=100

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

    文章里提到了几个误区,其中一个正是你所描述的。
    yueyoum
        23
    yueyoum  
    OP
       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
        24
    fengchang  
       2015-03-17 13:44:25 +08:00   ❤️ 1
    v2ex上有些人,开口就是你先去读xxx。

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

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

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

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

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

    我很好奇 到底什么坑?

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

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

    感谢认同我的感受。

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

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

    你说的对, 我表示赞同

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

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

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



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


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

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

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

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


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

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

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


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

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

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

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

    从这个意义上来说,是不是楼主说的“body部分非对称加密这种方式”,比TLS反而来得好?想听听您的评价,先谢个。
    Tr0y
        40
    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我。
    yyfearth
        41
    yyfearth  
       2015-03-17 14:42:29 +08:00   ❤️ 3
    @yueyoum 你确实是对这方面不太了解 虽然你实践过这些API
    但是如果你只用POST方法 那可以说就压根没有用到REST带来的任何好处 虽然实现起来比较方便

    Web Service/API 常用的大致有3种 比较早的 RPC 然后是 SOAP 最近才是流行 REST
    其中你的做法 实际上就是介于 RPC和SOAP 或者是更接近 RPC Style+JSON的做法
    首先 RPC和SOAP 都不适用HTTP的方法
    其中RPC一般来说读取用GET其他都用POST 也可以全部用POST(全部GET是非常糟糕的 但也有人这么做)
    而 SOAP 和你一样 全部用POST 只不过数据都是XML 而且有很严格的规范

    对于方法名 RPC和你一样 一般都是把方法名写在URL里面
    不过既然是放在URL里面 那么何必拘泥于这几个方法
    比如你可以直接映射Class里面的方法处理岂不是更直观 而且可以用生成器直接生成API
    比如 POST /userService/setUserById /userService/getUserById ...

    另外你说的 “配置文件写好简单的规则(xml) 自动生成代码” 这样的技术已经有了 就是 SOAP!
    SOAP 全部POST
    而且SOAP你定义好API规则后(WSDL) 客户端可以根据WSDL自动生成代码!
    而且SOAP的XML数据支持企业级加密
    主要的不同是你的数据是用JSON 而SOAP规范是用XML
    而且XML数据支持校验(DTD、Schema) 而目前JSON还没有这方面的标准

    REST 的好处 其实就是想要充分利用HTTP协议已经定义的东西
    比如Method 比如Status Code 比如无状态 比如GET PUT DELETE幂等(多次调用等于一次) 而且GET应该不改变状态 所以可以Cache之类的

    好了写了这么多 可以说楼主对现有的技术并不是很了解
    但是通过实践总结出了很多经验和模式
    但是如果你了解了现有的技术 其实你自己总结的很多东西 其实他们都已经考虑到了
    而且可能考虑的更远 自己是在从新发明轮子罢了
    或者你可以结合多种方案 找到你自己最喜欢的方案

    衷心的建议LZ了解一下这些技术 并且比较优劣 和使用场景
    https://zh.wikipedia.org/wiki/REST
    https://zh.wikipedia.org/wiki/SOAP
    https://zh.wikipedia.org/wiki/XML-RPC

    另外还有一个不常用方案 就是使用Websocket/Commet实现一个双向的消息队列MQ
    统一API入口 统一的数据格式 可以把方法名和参数封装在一个消息里面
    satanwoo
        42
    satanwoo  
       2015-03-17 14:44:26 +08:00
    @laoyur

    TLS是握手阶段用了非对称加密,在传输过程中还是对称加密传输。
    一般情况下,如果你信任了非认证的ca,被中间人流量劫持是很有可能的。
    learnshare
        43
    learnshare  
       2015-03-17 14:49:44 +08:00
    @crs0910 Ghost 这个 blog 是前后分离的,可以参考 https://github.com/TryGhost/Ghost

    https://github.com/TryGhost/Ghost/blob/master/core/server/routes/api.js 里面是 server 部分的 API,RESTful 的
    yyfearth
        44
    yyfearth  
       2015-03-17 14:53:25 +08:00   ❤️ 1
    @laoyur TLS本来就是非对称加密 至于证书的问题 你完全可以通过配置 让客户端严格检查证书即可
    我相信浏览器和一般的安全库是支持的 只不过对浏览器而言 控制权在用户手里
    另外我记得安装charles抓包的时候 你本地是可以信任证书的

    自己模仿这个实现一个简单的 当然可以 只不过还不一定比TLS 实现的好 效率也是个问题

    另外对于Web而言 不用https 你怎么加密都没用 因为中间人可以完全替换掉html或者js的内容
    直接加入恶意代码(比如这里经常讨论的ISP劫持弹广告)直接处理你加密之前或者解密之后的内容(相当于直接安装了一个木马) 加密就形同虚设了

    如果你真的非常注意安全 在https的前提下 对称或者非对称加密数据
    而且对于敏感数据 比如密码 可以使用不可逆加密(加盐Hash)
    zhicheng
        45
    zhicheng  
       2015-03-17 15:03:31 +08:00   ❤️ 1
    @laoyur
    这个不是协议的问题,是典型编码人员的疏忽。如果传输的是信用卡,密码等敏感数据的话,就是严重安全漏洞。对于能够犯这种错误的公司和工程师,即使你在 TLS 上再加一层加密,效果也不会强到哪里去。
    一个关于安全的建议,永远选择用的人最多的那个方案。比如 TLS,比如 PGP 。
    另外建议你可以多测试一些大公司的App,如果中间人成功,反馈给厂商应该会有奖金 :-)
    HowardMei
        46
    HowardMei  
       2015-03-17 15:10:38 +08:00
    @kxxoling 我也觉得如此,REST用在有些场景并不方便,另外对楼主"更安全"的说法不认可。
    下面表里Web Native的接口有很多,SOAP比REST更复杂,但还有JSON/XML-RPC啊
    http://wamp.ws/compared/
    dustinth
        47
    dustinth  
       2015-03-17 15:15:14 +08:00   ❤️ 1
    不懂Rest就开始谈设计不妥吧.
    laoyur
        48
    laoyur  
       2015-03-17 15:18:36 +08:00
    @satanwoo
    @yyfearth
    @zhicheng
    感谢回复。
    funsunz
        49
    funsunz  
       2015-03-17 15:44:33 +08:00   ❤️ 6
    我对RESTful的理解:
    HTTP协议是一个[应用层]协议,
    RESTful其实强调的, 就是重新认识这一点, 真正把HTTP当做应用层协议来用(相对于之前的webservice等将其作为传输层用):
    比如URI就真正对应你业务的抽象资源
    POST DELETE PUT GET这些HTTP协议定义的操作就真正对应你业务逻辑的增删改查
    ...
    这样, 所有懂得HTTP协议的人或机器, 就都能明白你操作的语义.


    我想楼主的意思是, 将HTTP完全作为传输层协议来使用.
    只用POST, HTTP_STATUS永远都是200, 服务器-客户端传输细节,状态等全部构建于HTTP协议的上层.
    在这种情况下, 楼主所说的"变得简单(简化)"是:
    因为HTTP被当做了传输层, 那么只要将这一层的框架搭好, 比如
    方法名(函数名)对应URI;
    请求参数对应REQUEST BODY (不用管参数一会在path中, 一会在query string 中, 一会在请求body中....);
    返回对应RESPONSE BODY.
    这样, HTTP层就变成透明的了, 请求过程就好像是客户端直接远程调用了服务器上的方法(函数)一样.

    如果是的话, 那本质上, 就是以前的webservice
    lqs
        50
    lqs  
       2015-03-17 15:48:03 +08:00   ❤️ 1
    现实很残酷:

    有些透明代理不允许除了 GET POST 之外的方法
    有些客户端会丢掉 PUT 请求中包含的 post data
    有些防火墙会把 non-2xx 响应中的内容都替换成它自己的页面

    当漂亮的 RESTful 设计遇到这些奇奇怪怪的实现,也只能妥协了。
    est
        51
    est  
       2015-03-17 16:09:57 +08:00   ❤️ 1
    @yueyoum 搞到最后,你发现URL都是多余的,直接一个 POST / ,然后在body里实现所有路由,分发,参数,签名,认证过程。

    其实这样更加安全,我知道StartSSL就是这样搞的。全站页面都是 /

    不过这样做有个问题:就是nginx/haproxy/varnish没法做负载均衡了。必须自己搞个支持9层路由分发的(HTTP是7层,JSON是8层,解密后的URL是9层) 。

    最后恭喜发财,你又造了个轮子。
    est
        52
    est  
       2015-03-17 16:16:13 +08:00
    @fengliu222 你的例子感觉也没举好。。。

    POST /transaction
    from=1&to=2&amount=100

    如果是 GET/HEAD/DELETE /transaction 感觉怪怪的。

    我感觉应该是这样:

    > 给 123这个角色 100 金币

    POST /player/123/gold
    amount=100
    zyue
        53
    zyue  
       2015-03-17 17:10:00 +08:00
    我是来看诸位写的rest url的...
    justfly
        54
    justfly  
       2015-03-17 17:33:17 +08:00
    看下来,这其实更像一场「得过且过,怎么方便怎么来,赶紧完活拿钱」和「愿意深究细节,代码洁癖,尽量完美」的态度之争吧。

    个人感觉。。。
    codegeek
        55
    codegeek  
       2015-03-17 18:15:47 +08:00
    除了get请求,其他请求也可以有body部分啊。
    picasso250
        56
    picasso250  
       2015-03-17 18:29:55 +08:00
    我是来支持楼主的。虽然我不会像楼主那么极端全部用POST。但是我确实会怎么写的快怎么来,怎么样bug少怎么来,最好是别人一看就懂。

    设想一个人问我API怎么设计的。我只需要告诉他我是RESTful的就行了吗?不行。不仅我需要在文档中写下各种请求方法,他还需要看文档,需要处理各种程度的细节。代码写的慢,bug还多。

    当然,我并不反对REST,相反,理解幂等的含义,并在自己的API中运用是很重要的,会减少很多可能的bug。

    毕竟,工程师是来(拯救世界)解决问题的,而非制造问题的。
    learnshare
        57
    learnshare  
       2015-03-17 18:43:37 +08:00
    @lqs “有些”不服,来几个“栗子”


    @est 全发到 / 上,相当于只有一个 API,用它干了所有的事情。耦合高,程序复杂,参数和状态到处都是
    xiaohanyu
        58
    xiaohanyu  
       2015-03-17 20:31:13 +08:00
    100% agree with @yyfearth
    xcv58
        59
    xcv58  
       2015-03-17 20:39:56 +08:00 via iPhone   ❤️ 1
    「你们写四个函数,我写一个函数就能解决问题了?」
    est
        60
    est  
       2015-03-17 21:48:34 +08:00   ❤️ 1
    @codegeek GET 其实也可以有body的
    zooandzoo
        61
    zooandzoo  
       2015-03-17 22:45:06 +08:00
    mark
    dalang
        62
    dalang  
       2015-03-18 00:04:03 +08:00   ❤️ 1
    最近一个项目设计 api 的时候跟一个前端沟通,对方也谈及类似思路。严格 REST 在有些条件下会遇到困难,比较常见的就有不使用 put 请求,全部使用 post。
    9hills
        63
    9hills  
       2015-03-18 00:23:39 +08:00
    @funsunz #49 这个理解赞。@yueyoum 的想法没错,只是找错了门路。

    lz其实不想要HTTP的那些语义,只是想把HTTP作为传输层。那么问题来了,HTTP其实不太适合做传输层,为什么不换其他的传输层呢。
    9hills
        64
    9hills  
       2015-03-18 00:30:23 +08:00
    另外对BODY加密就是脱裤子放屁多次一举,直接HTTPS好了。

    既然要好省快,却还要造不必要的轮子,也是不理解。。。
    puncsky
        65
    puncsky  
       2015-03-18 07:34:50 +08:00
    既然不是 RESTful API,就老老实实叫 HTTP API,不用赶时髦。
    caixiexin
        66
    caixiexin  
       2015-03-18 08:54:51 +08:00   ❤️ 1
    @funsunz 说的挺有道理。
    我觉得RESTful就是一种url组织方式吧,让设计的接口更http,更像资源而不是能力,有些场景下非常利于理解,比如各种开放平台的api。
    现在很多的RESTful api其实是一种妥协的RESTful,因为很多浏览器或客户端工具对put和delete支持不好,所以只用post和get方式,然后在url后面加个“create”“update”“delete”的动词表示post,put,delete,比如新浪微博的很多api
    说个最近用RESTFul体会到的好处,可以做到前后端完全分离,大大造福我们后端码农,经常接口开发完就给丢给前段,很多事都不用管了←_←
    ps:有时候我也很疑惑,RESTful好在哪里。程序员的世界就是天天有大牛提出新概念新技术试图引导技术潮流,我等码农能做到不在这个潮流中迷失就很不错了 = =
    wy315700
        67
    wy315700  
       2015-03-18 09:16:06 +08:00
    我举个例子

    POST是不允许重发的
    GET,PUT,DELETE都是在超时以后允许重发的。

    如果在设计的时候不按RESTful设计,可能就会出问题
    cloudzen
        68
    cloudzen  
       2015-03-18 09:19:00 +08:00
    RESTful不是银弹,亦如当年的AJAX
    min
        69
    min  
       2015-03-18 09:38:42 +08:00
    这套架构出来不少年了,业界已经有比较清楚的定义

    自己弄一套适合自己的用法没问题,但是和RESTful就没关系了
    mengzhuo
        70
    mengzhuo  
       2015-03-18 10:46:29 +08:00
    典型的书读的,设计也看的不多……
    repus911
        71
    repus911  
       2015-03-18 17:08:25 +08:00
    @est 你的例子才是错误的吧...
    est
        72
    est  
       2015-03-18 20:32:04 +08:00
    @repus911 那么什么是对的呢?
    fengliu222
        73
    fengliu222  
       2015-03-18 22:18:50 +08:00
    @est 我的例子纯属抄袭,原文在我提供的链接里。。
    yingluck
        74
    yingluck  
       2015-03-20 17:22:13 +08:00
    @est 试了一下 发现真的是 涨见识了
    这说明 HTTP动词是隔离于HTTP协议的
    感谢
    est
        75
    est  
       2015-03-20 18:02:33 +08:00
    @yingluck 但是这仅仅是RFC允许的而已。实际操作中。。。。。很多硬件软件都不支持这样干。
    yingluck
        76
    yingluck  
       2015-03-20 19:46:18 +08:00
    @est 硬件不支持? 您说的是防火墙过滤?
    这给我的启发是method仅仅是个名字而已,可以换套更贴合实际的新动词实现Restful API
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1006 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 22:21 · PVG 06:21 · LAX 14:21 · JFK 17:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.