RESTful API誊写规范

RESTful API誊写规范

办公室上网攻略--内网、外网、路由,自主控制

RESTful API誊写规范

 

基于一些不错的RESTful开发组件,可以快速的开发出不错的RESTful API,但若是不领会开发规范的、结实的RESTful API的基本面,即便优异的RESTful开发组件摆在面前,也无法很好的明白和使用。下文Gevin连系自己的实践经验,整理了从零开始开发RESTful API的焦点要点,完善的RESTful开发组件基本都市包罗所有或大部分要点,对于支持不够到位的要点,我们也可以自己写代码实现。

1. Request 和 Response

RESTful API的开发和使用,无非是客户端向服务器发请求(request),以及服务器对客户端请求的响应(response)。本真RESTful架构气概具有统一接口的特点,即,使用差别的http方式表达差别的行为:

  • GET(SELECT):从服务器取出资源(一项或多项)
  • POST(CREATE):在服务器新建一个资源
  • PUT(UPDATE):在服务器更新资源(客户端提供完整资源数据)
  • PATCH(UPDATE):在服务器更新资源(客户端提供需要修改的资源数据)
  • DELETE(DELETE):从服务器删除资源

客户端会基于GET方式向服务器发送获取数据的请求,基于PUT或PATCH方式向服务器发送更新数据的请求等,服务端在设计API时,也要凭据响应规范来处置对应的请求,这点现在应该已经成为所有RESTful API的开发者的共识了,而且各web框架的request类和response类都很壮大,具有合理的默认设置和天真的定制性,Gevin在这里仅准备强调一下响应这些request时,常用的Response要包罗的数据和状态码(status code),不完善的内容,迎接人人弥补:

  • 当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

最后,关于Request 和 Response,不要忽略了http header中的Content-Type。以json为例,若是API要求客户端发送request时要传入json数据,则服务器端仅做好json数据的获取和剖析即可,但若是服务端支持多种类型数据的传入,如同时支持json和form-data,则要凭据客户端发送请求时header中的Content-Type,对差别类型是数据划分实现获取和剖析;若是API响应客户端请求后,需要返回json数据,需要在header中添加Content-Type=Application/json。

2. Serialization 和 Deserialization

Serialization 和 Deserialization即序列化和反序列化。RESTful API以规范统一的花样作为数据的载体,常用的花样为json或xml,以json花样为例,当客户端向服务器发请求时,或者服务器响应客户端的请求,向客户端返回数据时,都是传输json花样的文本,而在服务器内部,数据处置时基本不用json花样的字符串,而是native类型的数据,最典型的如类的实例,即工具(object),json仅为服务器和客户端通讯时,在网络上传输的数据的花样,服务器和客户端内部,均存在将json转为native类型数据和将native类型数据转为json的需求,其中,将native类型数据转为json即为序列化,将json转为native类型数据即为反序列化。虽然某些开发语言,如Python,其原生数据类型list和dict能容易实现序列化和反序列化,但对于庞大的API,内部实现时总会以工具作为数据的载体,因此,确保序列化和反序列化方式的实现,是开发RESTful API最主要的一步准备工作

题外话,序列化和反序列化的便捷,作育了RESTful API跨平台的特点,使得REST取代RPC成为Web Service的主流

序列化和反序列化是RESTful API开发中的一项硬需求,以是险些每一种常用的开发语言都市有一个或多个优异的开源库,来实现序列化和反序列化,因此,我们在开发RESTful API时,没必要制造重复的轮子,选一个好用的库即可,如python中的marshmallow,若是基于Django开发,Django REST Framework中的serializer即可。

3. Validation

Validation即数据校验,是开发结实RESTful API中另一个主要的一环。仍以json为例,当客户端向服务器发出post, put或patch请求时,通常会同时给服务器发送json花样的相关数据,服务器在做数据处置之前,先做数据校验,是最合理和平安的前后端交互。若是客户端发送的数据不准确或不合理,服务器端经由校验后直接向客户端返回400错误及响应的数据错误信息即可。常见的数据校验包罗:

  • 数据类型校验,如字段类型若是是int,那么给字段赋字符串的值则报错
  • 数据花样校验,如邮箱或密码,其赋值必须知足响应的正则表达式,才是准确的输入数据
  • 数据逻辑校验,如数据包罗出生日期和岁数两个字段,若是这两个字段的数据不一致,则数据校验失败

以上三种类型的校验,数据逻辑校验最为庞大,通常涉及到多个字段的配合,或者要连系用户和权限做响应的校验。Validation虽然是RESTful API 编写中的一个可选项,但它对API的平安、服务器的开销和交互的友好性而言,都具有主要意义,因此,Gevin建议,开发一套完善的RESTful API时,Validation的实现必不可少。

4. Authentication 和 Permission

Authentication指用户认证,Permission指权限机制,这两点是使RESTful API 壮大、天真和平安的基本保障。

常用的认证机制是Basic Auth和OAuth,RESTful API 开发中,除非API异常简朴,且没有潜在的平安性问题,否则,认证机制是必须实现的,并应用到API中去。Basic Auth异常简朴,许多框架都集成了Basic Auth的实现,自己写一个也能很快搞定,OAuth现在已经成为企业级服务的标配,其相关的开源实现方案异常丰富(更多)。

我在《RESTful 架构气概概述》中,对认证机制做了加倍详细的形貌,有兴趣的同砚不妨阅读相关章节。

权限机制是对API请求更近一步的限制,只有通过认证的用户相符权限要求,才气接见API。权限机制的详细实现通常依赖于系统的营业逻辑和应用场景,generally speaking,常用的权限机制主要包罗全局型的和工具型的,全局型的权限机制,主要指通过为用户赋予权限,或者为用户赋予角色或划分到用户组,然后为角色或用户组赋予权限的方式来实现权限控制,工具型的权限机制,主要指权限控制的颗粒度在object上,用户对某个详细工具的接见、修改、删除或其行为,要单独在该工具上为用户赋予相关权限来实现权限控制。

全局型的权限机制容易明白,实现也简朴,有许多开源库可做备选方案,不少完善的web开发框架,也会集成相关的权限逻辑,object permission 相对难庞大一点,但也有许多典型的应用场景,如多人博客系统中,作者对自己文章的编辑权限即为object permission,其对应的开源库也有许多。

注: 我写过一篇《Django权限机制的实现》,Django 开发者可做延伸阅读。

开发一套完整的RESTful API,权限机制必须纳入思量局限,虽然权限机制的详细实现依赖于营业,权限机制自己,是有典型的模式存在的,需要开发者掌握基本的权限机制实现方案,以便随时应用到API中去。

5. CORS

CORS即Cross-origin resource sharing,在RESTful API开发中,主要是为js服务的,解决JAVAscript 挪用 RESTful API时的跨域问题。

由于固有的平安机制,js的跨域请求时是无法被服务器乐成响应的。现在前后端星散日益成为web开发主流方式的大趋势下,后台逐渐趋向指提供API服务,为各客户端提供数据及相关操作,而网站的开发所有交给前端搞定,网站和API服务很少部署在统一台服务器上并使用相同的端口,js的跨域请求时普遍存在的,开发RESTful API时,通常都要思量到CORS功效的实现,以便js能正常使用API。

现在各主流web开发语言都有许多优异的实现CORS的开源库,我们在开发RESTful API时,要注意CORS功效的实现,直接拿现有的轮子来用即可。

更多关于CORS的先容,有兴趣的同砚可以查看阮一峰先生的跨域资源共享 CORS 详解

6. URL Rules

RESTful API 是写给开发者来消费的,其命名和结构需要有意义。因此,在设计和编写URL时,要相符一些规范。Url rules 可以单独写一篇博客来详细论述,本文只列出一些要害点。

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/ 会感受何等不舒服。

6.3 GET and HEAD should always be safe

RFC2616已经明确指出,GET和HEAD方式必须始终是平安的。例如,有这样一个不规范的API:

# The following api is used to delete articles
# [GET]
/api/deleteArticle?id=1

试想,若是搜索引擎接见了上面url会若何?

6.4 Nested resources routing

若是要获取一个资源子集,接纳 nested routing 是一个优雅的方式,如,列出所有文章中属于Gevin编写的文章:

# List Gevin's articles
/api/authors/gevin/articles/

获取资源子集的另一种方式是基于filter(见下面章节),这两种方式都相符规范,但语义差别:若是语义上将资源子集看作一个自力的资源聚集,则使用 nested routing 感受更适当,若是资源子集的获取是出于过滤的目的,则使用filter更适当。

至于编写RESTful API时到底应接纳哪种方式,则仁者见仁,智者见智,语义上说的通即可。

6.5 Filter

对于资源聚集,可以通过url参数对资源举行过滤,如:

# List Gevin's articles
/api/articles?author=gevin

分页就是一种最典型的资源过滤。

6.6 Pagination

对于资源聚集,分页获取是一种对照合理的方式。若是基于开发框架(如Django REST Framework),直接使用开发框架中的分页机制即可,若是是自己实现分页机制,Gevin的计谋是:

返回资源聚集是,包罗与分页有关的数据如下:

{
 "page": 1, # 当前是第几页
 "pages": 3, # 总共若干页
 "per_page": 10, # 每页若干数据
 "has_next": true, # 是否有下一页数据
 "has_prev": false, # 是否有前一页数据
 "total": 27 # 总共若干数据
}

当想API请求资源聚集时,可选的分页参数为:

参数寄义page当前是第几页,默以为1per_page每页若干条纪录,默以为系统默认值

另外,系统内还设置一个per_page_max字段,用于符号系统允许的每页最大纪录数,当per_page值大于 per_page_max 值时,每页纪录条数为 per_page_max。

6.7 Url design tricks

(1)Url是区分大小写的,这点经常被忽略,即:

  • /Posts
  • /posts

上面这两个url是差别的两个url,可以指向差别的资源

(2)Back forward Slash (/)

现在对照盛行的API设计方案,通常建议url以/作为末端,若是API GET请求中,url不以/末端,则重定向到以/末端的API上去(这点现在的web框架基本都支持),由于有没有 /,也是两个url,即:

  • /posts/
  • /posts

这也是两个差别的url,可以对应差别的行为和资源

(3)连接符 - 和 下划线 _

RESTful API 应具备优越的可读性,当url中某一个片断(segment)由多个单词组成时,建议使用 - 来间隔单词,而不是使用 _,即:

# Good
/api/featured-post/
# Bad
/api/featured_post/

这主要是由于,浏览器中超链接显示的默认效果是,文字并附带下划线,若是API以_间隔单词,二者会重叠,影响可读性。

总结

编写本文的初衷,是为了整理一套从零开始编写规范、平安的RESTful API的基本思路。本文先容了开发RESTful API时,要思量的基本内容,对于类似Flask这种天生支持RESTful气概的web框架,不依赖其他RESTful第三方库开发RESTful 服务时,可以从本文内容入手;不少壮大的RESTful 库,虽然其相关接口基本涵盖了本文的所有或大部分内容,但本文的总结,信赖对这些库的明白和使用也是有辅助的。

ping命令的用法,收藏起来放着备用

分享到 :
相关推荐

发表评论

登录... 后才能评论