设计模式才是软件哲学的根本。。

一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

http的api设计艺术一直是个争论不休的命题, 话说,api接口本无标准,(确实没有标准)但是正确的设计模式和行业规范能够大大的方便用户和其他开发者, 同时开发新项目的时候减少自己思考的时间。我以前也很讨厌学习了解规范, 认为它约束了我们的代码, 减少了自由度,但是在工作中你不得不遵循团队的开发模式。就如同material design pattern一样,虽然它给艺术强加了一个‘标准’,但是大家都很喜欢她。

Restful api,Representational State Transfer, 就是api领域的一个规范,也是由http2.0开发者提出的一种通用方法,自从使用这主公规范以后, 我发现开发小型网站的效率一下子上去了。。。

请求方法的设计

http的经典做法是两个传递方向:请求和回应,请求的request有经典的method之选:

  • GET:读取(Read)
  • POST:新建(Create)
  • PUT:更新(Update)
  • PATCH:更新(Update),通常是部分更新
  • DELETE:删除(Delete)

很遗憾的是, 绝大多数人都只用前两个

这是个很悲剧的现象, 和http的创始人的构想相距甚远, 确实,只用post或者get完全能偶实现大多数应用, 但是几乎所有的 请求服务都分为增删改查(CRUD),而method就是为这个而设计的,如果不用method,你就得在url路径中制定哪种服务,比如:

  • /getAllUsers
  • /addNewUser
  • /dropOneUser
  • /setManyUsers

这简直太丑陋了!!

RESTful 的核心思想就是,客户端发出的数据操作指令都是"动词 + 宾语"的结构。比如,GET /articles这个命令,GET是动词,/articles是宾语。

由此可见,充分利用标准才能减少代码量, 使得逻辑更通顺,更可扩展

面向对象的思想

谈完了request,在谈谈http body体的设计:

这里主要是面向对象,即将body(json对象)中所有零碎的数据封装成一个个对象,如果只有一个对象就不需要引用名

设计公共API响应布局的目的是平衡消费者的易用性和提供者的稳定性承诺。我们可以依赖各种疯狂的元数据和嵌入式值,我们会后悔多年后保留它们,比如复杂的分页方案,这些方案不能扩展到不断扩展的域空间,或者当我们最终成为Web Scale并浪费数百万的额外带宽时从那个表情符号汤我们认为包装每个条目将是热闹的。

这个思想和函数参数列表是相通的(多参数封装对象, 单参数直接使用)

那些不适合CRUD的行为呢?

假如一个操作既get又set,这种组合是事情变得模糊的地方,既属于set也属于get。有很多例子:

  1. 将操作重组为显示为资源字段。如果操作不采用参数,则此方法有效。例如,激活动作可以映射到布尔激活的字段,并通过PATCH更新到资源。
  2. 将其视为具有RESTful原则的子资源。例如,GitHub的API让你用PUT / gists /:id / star和unstar与DELETE / gists /:id / star打造一个要点。
  3. 有时你真的无法将动作映射到合理的RESTful结构。例如,多资源搜索实际上没有意义应用于特定资源的端点。在这种情况下,即使它不是资源,/ search也会最有意义。这没关系 - 只需从API使用者的角度做正确的事情,并确保明确记录以避免混淆。

状态代码设计艺术

终于谈到response了,http返回包最重要是状态吗,请求只有几种,但返回结果有无数种可能,HTTP 状态码就是一个三位数,分成五个类别。

  • 1xx:相关信息
  • 2xx:操作成功
  • 3xx:重定向
  • 4xx:客户端错误
  • 5xx:服务器错误

这五大类总共包含100多种状态码,覆盖了绝大部分可能遇到的情况。每一种状态码都有标准的(或者约定的)解释,客户端只需查看状态码,就可以判断出发生了什么情况,所以服务器应该返回尽可能精确的状态码。

状态码对应请求的method,很多人有一个恶习就是状态统统不考虑, 通通200,但是错误信息卸载json中,比如:


HTTP/1.1 200 OK
Content-Type: application/json {
"status": "not ok",
code:1
"info": {
"error": "Permission Denied !!"
}
}

这种习惯是非常恶心的,好好的状态代码你不用,非要自定义,不是有病吗?要知道,fetch得到http第一个分组的时候就解析了response的promise,这时候就可以通过http头部的状态码来识别是否成功,如果非要自定协议就得等到http(流)完全结束后才能知道是否发生了错误,这是非常低效率的做法,虽然response对象还在试验阶段,但是随着投票人数的增多, 很快会成为标准化,大胆地用吧!

骚操作

restful的大致艺术就是如上,可见REST和CRUD还是很经典的概念,和unix定义的操作系统基本元素一样,几十年内是不会过时的,上米娜说到的规范当然不是全部, 我们还可以在api中添加一些彩蛋,充分利用上面讲到的所有的http元素来实现自己的骚操作,比如api的wiki:

API 的使用者未必知道,URL 是怎么设计的。一个解决方法就是,在回应中,给出相关链接,便于下一步操作。这样的话,用户只要记住一个 URL,就可以发现其他的 URL。这种方法叫做 HATEOAS。

举例来说,GitHub 的 API 都在 api.github.com 这个域名。访问它,就可以得到其他 URL。不信你可以点击试一试

关于restful风格和rpc风格的api设计和公司同事有过争论,感觉是主义之争,不会有什么结果。不过关于rest风格,在实际应用中,也遇到过难处理的问题,比如,client验证用户名或者电话是否存在,就不知如何设计怎么好,最后“强行”设计成:GET /users/checking(validating)?username=xx,反倒是,rpc风格,GET /users.check?username=xx是否表达力更强一些。再如,某个操作导致状态更新,总结下,就是对于有很强的“动作”在内的api,restful风格并不完全适用,只是稍微有点麻烦。

综上所述,合理的restful设计可以满足日常生活中99%的需求,让开发者感到‘ very restful’

Restful --- 让JSON回归单纯的更多相关文章

  1. CXF(2.7.10) - RESTful Services, JSON Support

    在 CXF(2.7.10) - RESTful Services 介绍了 REST 风格的 WebService 服务,数据传输是基于 XML 格式的.如果要基于 JSON 格式传输数据,仅需要将注解 ...

  2. Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

    很多时候前端都需要调用后台服务实现交互功能,常见的数据交换格式多是JSON或XML,这里主要讲解Spring MVC为前端提供JSON格式的数据并实现与前台交互.RESTful则是一种软件架构风格.设 ...

  3. RESTful处理JSON

    @RequestMapping(value = "/dblist", method = RequestMethod.GET) @ResponseBody public Map< ...

  4. delphi7的新生,参与分布式应用开发,调用RESTful API,Json的应用

    前言: 1.公司delphi7开发的传统软件还活得好好的,但是大家都知道delphi早已经日落西山了,现在成了后进.追随者.细细算了已经6.7不用了.新的delphixe7呢,没有时间成本去适应和研究 ...

  5. 一百零一:CMS系统之自定义restful风格json返回格式和内容

    鉴于flask-restful用起来太麻烦,这里自定义json统一返回格式和内容 from flask import jsonify class HttpCode: """ ...

  6. restful返回 json数据的JavaBean设计01

    public class ResponseEntity implements Serializable { private int errCode; private String message; p ...

  7. Yii2框架RESTful API教程(二) - 格式化响应,授权认证和速率限制

    之前写过一篇Yii2框架RESTful API教程(一) - 快速入门,今天接着来探究一下Yii2 RESTful的格式化响应,授权认证和速率限制三个部分 一.目录结构 先列出需要改动的文件.目录如下 ...

  8. Apache CXF实现Web Service(2)——不借助重量级Web容器和Spring实现一个纯的JAX-RS(RESTful) web service

    实现目标 http://localhost:9000/rs/roomservice 为入口, http://localhost:9000/rs/roomservice/room为房间列表, http: ...

  9. nova创建虚拟机源码分析系列之一 restful api

    开始学习openstack源码,源码文件多,分支不少.按照学习的方法走通一条线是最好的,而网上推荐的最多的就是nova创建虚机的过程.从这一条线入手,能够贯穿openstack核心服务.写博文仅做学习 ...

随机推荐

  1. 分享一款眼睛保健小软件 EyeDefender 多关注下眼睛的健康

    http://www.nowamagic.net/librarys/veda/detail/2248 感觉最近视力又下降了不少,估计又要重新配眼镜了.总是对着电脑一坐就好几个小时,眼睛老是紧绷着,焦距 ...

  2. 【js】replace()

    replace方法的语法是: stringObj.replace(rgExp, replaceText) 其中stringObj是字符串(string),reExp可以是正则表达式对象(RegExp) ...

  3. BIP_BI Pubisher的SQL/XSL/FO扩展函数应用(概念)

    2014-12-01 Created By BaoXinjian

  4. PLSQL_统计信息系列08_统计信息生成和还原

    2015-02-01 Created By BaoXinjian

  5. socket 请求接收完整的一个http响应(设置recv 接收超时选项SO_RCVTIMEO)

    在前面的系列网络编程文章中,我们都是使用socket 自己实现客户端和服务器端来互相发数据测试,现在尝试使用socket 客户端发 送http 请求给某个网站,然后接收网站的响应数据.http 协议参 ...

  6. Unix环境高级编程(十)信号续

    1.signal函数 Unix系统的信号机制最简单的接口是signal函数,函数原型如下: #include <signal.h> typedef void (*sighandler_t) ...

  7. Hive学习之函数DDL和Show、Describe语句

    创建/删除函数 创建暂时函数 以下的语句创建由class_name实现的暂时函数,该函数被创建后仅仅能够在当前会话中使用.会话结束后函数失效. 实现函数的类能够是Hive类路径中的随意类.能够使用Ad ...

  8. 关于centos7中使用rpm方式安装mysql5.7版本后无法使用root登录的问题

    最近在centos7中通过rpm方式安装了最新版本的mysql-server 5.7 (mysql57-community-release-el7-7.noarch.rpm) ,发现安装成功后无法使用 ...

  9. C# 查看动态库的方法

    使用Vs自带工具:开始菜单-->Microsoft Visual Studio 2010--> Visual Studio Tools-->Visual Studio 命令提示符 输 ...

  10. linux用户管理之创建用户和删除用户

    一.常用命令: (1)创建用户命令两条: adduser useradd (2)用户删除命令: userdel 二.两个用户创建命令之间的区别 adduser: 会自动为创建的用户指定主目录.系统sh ...