在这篇文章中,我会通过REST规范的应用和优质的实例来展示RESTfulAPI设计规范的基本原理。
如果你已经知道API在RESTful Web Service的背景下的含义,可以跳过下一段。如果没有,继续读下去。
API上的水平集
API是Application Programming Interface的缩写,单词本身并不能帮助我们理解它是什么,但是在Web Service的背景下,它可以指以下两种情况的任意一种:
- RESTful API规范是用模型化语言编写的,像Open API规范或者Raml(RESTful API Modeling Language),它是一个明确了组件如何与服务交互的协议。
- Web Service或微服务的执行协议是由REST设计规范的,它描述了其他服务如何与之交互。
在这篇文章中,我用的是这个术语的第一个理解。虽然两者都是正确的,但在本文中最相关的是第一个:API是一个软件应用程序之间怎么沟通的协议。
REST上的水平集
REST是REpresentational State Transfer的缩写,是一种结构样式,用于组件之间的数据传输。在Web Service的背景下,我们通常说的是数据传输在http中的描述,通过调用包含数据的URI和根据已知数据执行操作的HTTP方法。
什么是RESTful API设计?
RESTful API设计是基于Web Service的数据结构、和你允许其他应用程序组件根据REST规范对其数据执行操作的行动。
为什么要设计restful api?
想象一下,有一名建筑设计师,要在没有蓝图的情况下建造一栋办公楼。第一天他就只开着一辆装满砖头和水泥的卡车到工地,这时候他要构建一个符合规范、且一次成功的架构的可能性有多大?只可能是0,没有蓝图失败的几率太高了。
同样的态度也适用于web service开发。我们需要一个蓝图,更准确地说,一个API规范。在开始开发执行之前,这是评估api设计和请求反馈的必要条件。
除了为Web Service的开发明确规范之外,这个API协议还可以用来记录API的预期行为、数据类型和安全性需求。(?)
看到这里应该都知道了API设计对于RESTful Web Service的必要性,接着就要开始思考什么是最好的API设计规范方法了。
API设计工具
API设计人员选择的工具对他们的生产力有很大的影响。像MuleSoft的anypointapi Designer这样的工具比较适合用OAS(swagger)或RAML设计API。
另外Eolinker对于效率提升的帮助也很大,低代码且支持多种格式导出。
RESTful API规范语言
API设计者可以选择多种架构语言,每种语言都有描述restful api的方法,但每种语言都遵循REST体系的结构样式。最广泛采用的选择是:
• RAML
• Swagger
• Blueprint
在这篇文章中,我将用RAML设计一个API。
用RAML设计REST API
要用RESTful API设计协议,需要从REST体系结构风格的角度定义底层服务的行为,这意味着识别以下方面:
• 端点
• HTTP方法
• HTTP请求和响应的格式
用例上下文
现在我需要设计一个API来表述员工的数据。这个API应该描述准许查询员工资料的功能,API规范还应该记录用户数据类型并提供示例。
定义API Header
让我们从定义API规范的header开始。
#%RAML 1.0
title: Employees API
baseUri: http://example.com/api/{version}
version: v1
其中定义了标题、版本和基础URI,实现API的绝对URL。
定义资源
接下来要定义端点URI。这些标识表示员工数据的资源,以及可以针对其执行CRUD功能的资源。
根据REST协议,资源URI应该命名为与其表示的数据相关的名词。下表显示了如何查找公共资源的示例:
数据类型 资源URL
Employee data /employees
Product data /products
Flight data /flights
如果资源代表一个集合,那么其逻辑应该是多元化的。预期的情况是对GET/employees端点的调用会返回一个雇员列表(即使数组只包含一个雇员)。根据RAML语法,资源URI以冒号结尾:
/employees:
调用资源URI使用HTTP方法
Restful api设计时通常使用五种HTTP方法。它们会映射到CRUD功能,如下所示:
• POST(映射为创建)
• GET(映射为读)
• PUT(映射到更新)
• DELETE(映射到删除)
• PATCH(映射到部分更新)
根据REST规范,GET和POST(读取和创建)方法与资源方法与作为单个URI资源的资源表示一起使用,因为它们不针对特定的可标识资源,例如GET /employees和POST /employees。对于DELETE、PUT和PATCH(删除、更新和局部更新)方法,使用的资源表示包括标识正在更改的资源的URI变量,如DELETE /employees/{employeeID} 和PUT /employees/{employeeID}.
/employees:
get:
post:
/{employeeID}:
put:
delete:
定义HTTP请求
设计RESTfulAPI的一个本质需求是为客户端提供足够的详细信息,才知道如何进行验证请求。
例如,POST /employee/{employeeId}Http请求应该有一个包含要在目标系统中创建的员工详细信息的主体。API规范应该包括一个数据类型定义和一个有效格式的雇员数据示例。
它也是一种协议,用于指定数据如何表示。定义为MIME类型,可以是许多类型之一,比如最常见的类型:json和xml。
在下面的Raml中,定义了Employee GET、POST和PUT端点。我们可以看到规范中包含了一个雇员数据示例,并定义了数据将被导出为JSON。
/employees:
get:
post:
body:
application/json:
example: |
{
"firstName" : "John",
"lastname" : "Smith"
}
/{employeeID}:
put:
body:
application/json:
example: |
{
"firstName" : "John",
"lastname" : "Smith"
}
delete:
定义HTTP响应和HTTP状态代码
HTTP状态代码与HTTP请求的响应一起发送,并在五个类别中指示请求的状态。状态代码的第一个数字标识响应的状态。
• 1XX-信息
• 2XX-成功
• 3xx-重导
• 4xx-客户端错误
• 5xx-服务器错误
所有状态代码的详细信息都可以在网络上找到。.
接着为GET和DELETE方法定义一个响应。其中定义了一个用于GET请求的200个代码来表示成功,还定义了一个204响应来表示删除成功,但是响应主体不包括已删除资源的表述。
/employees:
get:
description: Retrieve the list of all employees
responses:
200:
body:
application/json:
example: |
{
"firstName" : "John",
"lastname" : "Smith"
}
post:
/{employeeID}:
put:
delete:
responses:
204:
description: The delete request has been successfully executed.
完整的API规范
把所有的部分放在一起,完成API的设计:
#%RAML 1.0
title: Employees API
baseUri: http://example.com/api/{version}
version: v1
/employees:
get:
description: Retrieve a list of all employees
responses:
200:
body:
application/json:
example: |
{
"firstName" : "John",
"lastname" : "Smith"
}
post:
body:
application/json:
example: |
{
"firstName" : "John",
"lastname" : "Smith"
}
/{employeeID}:
put:
body:
application/json:
example: |
{
"firstName" : "John",
"lastname" : "Smith"
}
delete:
responses:
204:
description: The delete request has been successfully executed.
结语
这篇文章中,只介绍了RESTfulAPI设计的基础和Raml,帮助了解了如何定义资源、方法、请求和响应。希望对大家有所帮助。