ORM
的技术,随着NoSQL的发展,又出现了OGM
,ODM
REST即Representational State Transfer的缩写,可译为"表现层状态转化”。REST最大的几个特点为:资源、统一接口、URI和无状态。
一、Request
- GET(SELECT):从服务器取出资源(一项或多项)
- POST(CREATE):在服务器新建一个资源
- PUT(UPDATE):在服务器更新资源(客户端提供完整资源数据)
- PATCH(UPDATE):在服务器更新资源(客户端提供需要修改的资源数据)
- DELETE(DELETE):从服务器删除资源
二、Response
- 当GET, PUT和PATCH请求成功时,要返回对应的数据,及状态码200,即SUCCESS
- 当POST创建数据成功时,要返回创建的数据,及状态码201,即CREATED
- 当DELETE删除数据成功时,不返回数据,状态码要返回204,即NO CONTENT
- 当GET 不到数据时,状态码要返回404,即NOT FOUND
- 任何时候,如果请求有问题,如校验请求数据时发现错误(参数不对),要返回状态码 400,即BAD REQUEST
- 当API 请求需要用户认证时,如果request中的认证信息不正确,要返回状态码 401,即NOT AUTHORIZED
- 当API 请求需要验证用户权限时,如果当前用户无相应权限,要返回状态码 403,即FORBIDDEN
三、Serialization & Deserialization
- native类型数据转为json即为序列化,将json转为native类型数据即为反序列化。
- python中的marshmallow,实现序列化和反序列化。
- jsonify的作用是,把dict或list转换为string(类似于json.dumps()),obj序列化只要把obj包含的数据,转化到dict。同时,在response的header中,添加content-type =application/json,由于RESTful API通常以json格式作为载体,该方法算是一个shortcut。
- Flask中如果数据载体为 json,只需调用 request.get_json()方法,即可将传入的文本数据转换为dict或list。
四、Validation
常见的数据校验包括:
- 数据类型校验,如字段类型如果是int,那么给字段赋字符串的值则报错
- 数据格式校验,如邮箱或密码,其赋值必须满足相应的正则表达式,才是正确的输入数据
- 数据逻辑校验,如数据包含出生日期和年龄两个字段,如果这两个字段的数据不一致,则数据校验失败
五、Authentication 和 Permission
Authentication指用户认证,Permission指权限机制,这两点是使RESTful API 强大、灵活和安全的基本保障。
六、URL Rules
RESTful API 是写给开发者来消费的,其命名和结构需要有意义。因此,在设计和编写URL时,要符合一些规范。
6.1 Version your API
规范的API应该包含版本信息,在RESTful API中,最简单的包含版本的方法是将版本信息放到url中,如:
/api/v1/posts/
/api/v1/drafts/
/api/v2/posts/
/api/v2/drafts/
另一种优雅的做法是,使用HTTP header中的accept来传递版本信息,这也是GitHub API 采取的策略。
6.2 Use nouns, not verbs
RESTful API 中的url是指向资源的,而不是描述行为的,因此设计API时,应使用名词而非动词来描述语义,否则会引起混淆和语义不清。即:
# Bad APIs
/api/getArticle/1/
/api/updateArticle/1/
/api/deleteArticle/1/
上面四个url都是指向同一个资源的,虽然一个资源允许多个url指向它,但不同的url应该表达不同的语义,上面的API可以优化为:
# Good APIs
/api/Article/1/
article 资源的获取、更新和删除分别通过 GET, PUT 和 DELETE方法请求API即可。试想,如果url以动词来描述,用PUT方法请求 /api/deleteArticle/1/ 会感觉多么不舒服。
分页
包含与分页有关的数据如下:
{
"page": 1, # 当前是第几页
"pages": 3, # 总共多少页
"per_page": 10, # 每页多少数据
"has_next": true, # 是否有下一页数据
"has_prev": false, # 是否有前一页数据
"total": 27 # 总共多少数据
}
另外,系统内还设置一个per_page_max字段,用于标记系统允许的每页最大记录数,当per_page值大于 per_page_max 值时,每页记录条数为 per_page_max。
七、URL Rules
所谓无状态的,即所有的资源,都可以通过URI定位,而且这个定位与其他资源无关,也不会因为其他资源的变化而改变。
八、认证机制
由于RESTful风格的服务是无状态的,认证机制尤为重要。如果不通过权限认证机制对资源做一层限制,那么所有资源都以公开方式暴露出来,这是不合理的,也是很危险的。
认证机制解决的问题是,确定访问资源的用户是谁;权限机制解决的问题是,确定用户是否被许可使用、修改、删除或创建资源。权限机制通常与服务的业务逻辑绑定,因此权限机制需要在每个系统内部定制,而认证机制基本上是通用的,常用的认证机制包括 session auth(即通过用户名密码登录),basic auth,token auth和OAuth,服务开发中常用的认证机制为后三者。
8.1 Basic Auth
Basic Auth是配合RESTful API 使用的最简单的认证方式,只需提供用户名密码即可,但由于有把用户名密码暴露给第三方客户端的风险,在生产环境下被使用的越来越少。因此,在开发对外开放的RESTful API时,尽量避免采用Basic Auth
8.2 Token Auth
Token Auth并不常用,它与Basic Auth的区别是,不将用户名和密码发送给服务器做用户认证,而是向服务器发送一个事先在服务器端生成的token来做认证。因此Token Auth要求服务器端要具备一套完整的Token创建和管理机制,该机制的实现会增加大量且非必须的服务器端开发工作,也不见得这套机制足够安全和通用,因此Token
Auth用的并不多。
8.3 OAuth
OAuth(开放授权)是一个开放的授权标准,允许用户让第三方应用访问该用户在某一web服务上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。
OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的第三方系统(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。
正是由于OAUTH的严谨性和安全性,现在OAUTH已成为RESTful架构风格中最常用的认证机制,和RESTful架构风格一起,成为企业级服务的标配。
目前OAuth已经从OAuth1.0发展到OAuth2.0,但这二者并非平滑过渡升级,OAuth2.0在保证安全性的前提下大大减少了客户端开发的复杂性,因此,Gevin建议在实战应用中采用OAuth2.0认证机制。
现在网上关于OAuth的资料非常丰富,也有大量开源的第三方库实现了OAuth机制,不熟悉OAuth的同学从OAuth官网入手即可。
九、总结
- 本真REST + OAuth是RESTful 是微服务的标配
- Basic Auth只在开发环境中使用
- 设计合理的资源
- 用正确的HTTP方法对数据发正确的请求
网友评论