REST(英文:Representational State Transfer,又称具象状态传输)是Roy Thomas Fielding博士于2000年在他的博士论文 中提出来的一种万维网软件架构风格,目的是便于不一样软件/程序在网络(例如互联网)中互相传递信息。html
REST 的核心是可编辑的资源及其集合,用符合 Atom 文档标准的 Feed 和 Entry 表示。每一个资源或者集合有一个唯一的 URI。系统以资源为中心,构建并提供一系列的 Web 服务。python
在 REST 中,开发人员显式地使用 HTTP 方法,对系统资源进行建立、读取、更新和删除的操做:git
使用 POST 方法在服务器上建立资源github
使用 GET 方法从服务器检索某个资源或者资源集合web
使用 PUT 方法对服务器的现有资源进行更新数据库
使用 DELETE 方法删除服务器的某个资源编程
若是一个架构符合REST原则,就能够称它为RESTful架构
。json
如下是几个RESTful API的几个概念。flask
资源(Resource):系统上的全部事物都被抽象为资源(一篇文章,一张照片,一段语音)api
集合(Collection):一组资源的合辑称为集合(几篇文章,几张照片)
路径(Endpoint):路径又称”终点“,表示API的具体网址(每一个网址表明一种资源)
那么一个设计良好的RESTful API应该遵循哪些原则呢?
API与用户的通讯协议老是使用HTTPs协议。
应该尽可能将API部署在专用域名,例如:
https://apis.gusibi.com
在url中指定API版本。好比:
https://apis.gusibi.com/v1
资源是RESTful API的核心元素,全部的操做都是针对特定资源进化的。而资源就是URL表示的,因此简洁、清晰、结构化的URL设计是相当重要的。
在RESTful 架构中,每一个网址表明一种资源(resource),因此网址中不能有动词,只能有名词,并且所用的名词每每与数据库的表格名对应。咱们来看一下 Github 的例子:
/users/:username/repos /users/:org/repos /repos/:owner/:repo /repos/:owner/:repo/tags /repos/:owner/:repo/branches/:branch
对于资源的具体操做类型,使用HTTP method 表示。
如下是经常使用的HTTP方法。
GET:从服务器取出资源
POST:在服务器新建一个资源
PUT:在服务器更新资源(客户端提供改变后的完整资源
PATCH:在服务器更新资源(客户端只提供改变了属性)
DELETE:从服务器删除资源
仍是使用 github 的例子:
GET /repos/:owner/:repo/issues GET /repos/:owner/:repo/issues/:number POST /repos/:owner/:repo/issues PATCH /repos/:owner/:repo/issues/:number DELETE /repos/:owner/:repo
若是记录数量不少,服务器不能都将他们返回给用户。API应该提供参数,过滤返回结果。
下边是一些是、常见的参数。
?limit=10: 指定返回记录的数量
?offset=10:指定返回记录的开始位置
?page=2&per_page=100::指定第几页,以及每页的记录数。
?sortby=name&order=asc:指定返回结果按照哪一个属性排序,以及排序顺序。
?animal_type_id=1:指定筛选条件
HTTP 应答中,须要带一个很重要的字段:status code。它说明了请求的大体状况,是否正常完成、须要进一步处理、出现了什么错误,对于客户端很是重要。状态码都是三位的整数,大概分红了几个区间:
2XX:请求正常处理并返回
3XX:重定向,请求的资源位置发生变化
4XX:客户端发送的请求有错误
5XX:服务器端错误
常见的状态码有如下几种:
200 OK - [GET]:服务器成功返回用户请求的数据,该操做是幂等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
204 NO CONTENT - [DELETE]:用户删除数据成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操做,该操做是幂等的。
401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
403 Forbidden - [*] 表示用户获得受权(与401错误相对),可是访问是被禁止的。
404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操做,该操做是幂等的。
406 Not Acceptable - [GET]:用户请求的格式不可得(好比用户请求JSON格式,可是只有XML格式)。
410 Gone -[GET]:用户请求的资源被永久删除,且不会再获得的。
422 Unprocesable entity - [POST/PUT/PATCH] 当建立一个对象时,发生一个验证错误。
500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将没法判断发出的请求是否成功。
针对不一样操做,服务器向用户返回的结果应该符合如下规范。
GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档
若是出错的话,在response body 中经过 message 给出明确的信息。若是状态码是4xx,就应该向用户返回出错信息。
文档应该是规范的API的重要的组成部分,没有文档的API是难以给他人使用的,也是不利于维护的。
使用 OAuth2.0 鉴权
尽可能使用JSON做为返回的数据格式
限流
对应上述规则,咱们并不能保证其它的API提供者也会遵照,特别是文档,有很大一部分API提供者给出的文档是pdf或者word文档,这是由于在API的迭代开发过程当中,文档更新会比较麻烦。
swagger帮API使用者和开发者纠正了这个问题。
Swagger是一个简单但功能强大的API表达工具。改框架为建立JSON或YAML格式的RESTful API 文档提供了OpenAPI规范。swagger文档可由各类编程语言处理,能够在软件开发周期中嵌入源代码控制系统中,以便进行版本管理。使用Swagger生成API,咱们能够获得交互式文档,自动生成代码的SDK以及API的发现特性等。
咱们能够选择使用JSON或者YAML来编写API文档。文档示例以下:
json 格式文档:
{ "swagger": "2.0", "info": { "version": "1.0.0", "title": "Simple API", "description": "A simple API to learn how to write OpenAPI Specification" }, "schemes": [ "https" ], "host": "simple.api", "basePath": "/openapi101", "paths": { "/persons": { "get": { "summary": "Gets some persons", "description": "Returns a list containing all persons.", "responses": { "200": { "description": "A list of Person", "schema": { "type": "array", "items": { "properties": { "firstName": { "type": "string" }, "lastName": { "type": "string" }, "username": { "type": "string" } } } } } } } } } }
yaml 格式文档:
swagger: "2.0" info: version: 1.0.0 title: Simple API description: A simple API to learn how to write OpenAPI Specification schemes: - https host: simple.api basePath: /openapi101 paths: /persons: get: summary: Gets some persons description: Returns a list containing all persons. responses: 200: description: A list of Person schema: type: array items: required: - username properties: firstName: type: string lastName: type: string username: type: string
能够发现,yaml格式的文档比json格式的更清晰,可读性更高,推荐使用yaml格式书写文档。
swagger 官网提供了 swagger editor: http://editor.swagger.io/#/,你能够在这个编辑器中建立或导入文档,并在交互式环境中浏览它。
如下是您导入 leads.yaml 定义后的 Swagger Editor UI 外观:
右侧的显示窗格显示了格式化的文档,反映了在左侧窗格中的代码编辑器中执行的更改。代码编辑器会指出了全部格式错误。你能够展开和折叠每一个窗格。
我用一个例子来介绍下swagger文档的基本结构,这里我用yaml格式来编写文档:
swagger: "2.0" info: title: Sample API description: API description in Markdown. version: 1.0.0 host: api.example.com basePath: /v1 schemes: - https paths: /users: get: summary: Returns a list of users. description: Optional extended description in Markdown. produces: - application/json responses: 200: description: OK
上述文档包括元数据(Metadata)、Base URL、API路径(paths)三部分:
这部分信息包括swagger 使用的版本:
swagger: "2.0"
API相关的描述信息(好比API介绍、版本等):
info: title: Sample API description: API description in Markdown. version: 1.0.0
做为web API,一个很重要的信息就是用来给用户使用的 根URL,可用协议(http/https)、host地址:
host: api.example.com basePath: /v1 schemes: - https
全部的API都是base URL 的相对路径 例如 /users 的API地址是 https://api.example.com/v1/users
。
paths 部分定义API的路径(endpoint)、支持的HTTP 请求方法
paths: # 声明路径 /users: # 定义API路径 get: # 定义请求方式 summary: Returns a list of users. # 简介 description: Optional extended description in Markdown. # 描述 produces: - application/json # 定义 服务端response MIME types responses: 200: # response 状态码 description: OK
固然这只是个最简单的例子,swagger可定义的内容要比我提到的多的多。
具体详细信息能够看下 swagger 文档:https://swagger.io/docs/specification/what-is-swagger/。
固然,写完文档并不表明咱们的代码就能够直接使用这份文档以及文档中的约束,swagger 还提供了 swagger-codegen:https://github.com/swagger-api/swagger-codegen。
swagger-codegen 是一个开源的代码生成工具,它包含一个模板驱动引擎,能够直接从咱们定义的 swagger 文档中生成可视化的文档查看界面和API客户端。
这是一个开源的项目,地址是swagger-codegens: https://github.com/swagger-api/swagger-codegen。能够本身安装使用一下。
由于我最经常使用的语言是Python,因此给你们介绍一个第三方的 python 的代码生成器swagger-py-codegen:https://github.com/guokr/swagger-py-codegen
swagger-py-codegen的亮点是它是一个Python web framework 代码生成器,能够根据swagger 文档自动生成相应web framework 的代码,如今支持 Flask, Tornado,falcon,最新版将支持sanic。
可使用 pip 安装:
pip install swagger-py-codegen
安装后使用命令以下:
swagger_py_codegen --swagger-doc api.yml example-app
可选参数有:
-s, --swagger, --swagger-doc Swagger doc file. [required] -f, --force Force overwrite. -p, --package Package name / application name. -t, --template-dir Path of your custom templates directory. --spec, --specification Generate online specification json response. --ui Generate swagger ui. -j, --jobs INTEGER Parallel jobs for processing. -tlp, --templates gen flask/tornado/falcon templates, default flask. --version Show current version. --help Show this message and exit.
若是不指定 -tlp 参数,默认使用 flask 做为模板。
若是指定 --ui --spec 参数则会在 由-p 参数指定的目录下生成swagger UI 目录 static。
咱们这里使用 swagger-py-codegen 提供的测试文档 执行:
swagger_py_codegen --swagger-doc api.yml example-app --ui --spec
生成的代码目录结构以下
$tree . |__ api.yml $ swagger_py_codegen -s api.yml example-app -p demo $ tree (flask-demo) . |__ api.yml |__ example-app |__ demo | |__ __init__.py | |__ v1 | |__ api | | |__ __init__.py | | |__ oauth_auth_approach_approach.py | | |__ oauth_auth_approach.py | | |__ users_token.py | | |__ users_current.py | | |__ users.py | |__ __init__.py | |__ routes.py | |__ schemas.py | |__ validators.py |__ requirements.txt
能够看到,这时一个简单的app框架已经生成了,其中 routes.py 是自动生成的路由,validators.py 是response和request的校验代码,schemas.py 是由文档生成的校验规则,api 目录下的各个文件是你定义的endpoint。
这时运行demo 目录下的 __init__.py
文件:
python __init__.py
会发现 server 已经启动:
若是生成命令带上 --ui --spec,生成代码的同时也会生成swagger UI:
swagger_py_codegen --swagger-doc api.yml example-app --ui --spec
启动server后在浏览器输入地址 http://0.0.0.0:8000/static/swagger-ui/index.html#!/default/get_users_uid
能够看到直接使用的 swagger UI。
swagger-py-codegen 认证默认使用 OAuth2 认证方式,认证部分代码须要本身实现。
如今代码结构已经生成,能够安心的写逻辑代码了。
这一篇主要介绍了RESTful API以及如何使用swagger编写规范的RESTful API。
最后介绍了如何使用 swagger-py-codegen 生成 web framework 的结构代码。
参考连接中的文章都很是值得一看,建议都看一下。
最后,感谢女友支持。
欢迎关注(April_Louisa) | 请我喝芬达 |
---|---|
![]() |
![]() |