RESTful API设计

本文详细介绍了RESTful API的概念及其优势,强调了标准RESTful API的规范,如使用HTTPS协议、专有域名、版本控制、资源表述、操作行为、过滤和状态码。同时,提供了复杂API设计示例,如任务开启/关闭、用户任务设置、关注/取消关注、登录/登出。还探讨了简化RESTful API时对状态码的调整和返回结果的统一格式。最后,提及了HATEOAS的概念,并给出了参考链接。

一、RESTful API简介

restful

1.1 RESTful API是什么

RESTful API全称是Resource Representational State Transfer(资源表述性状态转移)。

R:Resource 资源。例如:user、role、gist、issue、service、route

E:Representational 表述性。数据的表现形式,例如:JSON、XML、CSV、IMG等

S:State 状态。资源的状态,例如:创建、更新等状态

T:Transfer 转移。通过HTTP METHOD,例如:GET、POST、PUT、PATCH、DELETE

RESFful并没有创造任何新的技术或者服务,它是一种架构设计风格,包含一系列的约束条件和原则,只要架构符合该约束条件和原则,我们就称它为RESTful架构。

1.2 为什么使用Restful API

因为它将一个应用的资源、行为、状态都统一到一个设计体系下,API的定义更符合人的认知。在面对一个符合Restful API的未知应用时,你可以很清楚知道,先了解有整个系统有那些资源对象和他们之间的关系,进一步了解资源有哪些行为(在有限的范围内,例如GET、POST、PUT),然后就可以掌握对整个系统的认识和使用,进一步可以构建HATEOAS体系。

反之,非RESTful API则需要查看所有API文档,即便如此,查看后也无法掌握整个系统,因为你不知道有那些可操作性对象,同时一个API也可能包含相反的操作(例如删除一些记录,同时又创建了许多记录)和多个面向对象。

二、标准Restful API

2.1 协议

API与用户通信协议,总是使用HTTPS协议。

//正确示例
https://{api}.restful.com
//错误示例
http://{api}.restful.com

2.2 域名

API应尽量使用专有域名和基路径。

//正确示例
https://{api}.restful.com/api
//错误示例
https://{api}.restful.com/api

2.3 版本

第一种方式,将API的版本号放入URL中。

//正确示例
https://{api}.restful.com/api/v1/routes
//错误示例
https://{api}.restful.com/v1/api/routes

https://{api}.restful.com/api/routes/v1

第二种方式,将API的版本号放入HTTP头信息中。

//正确示例
version: v1
https://{api}.restful.com/api/routes
//错误示例
https://{api}.restful.com/api/routes

2.4 资源

在RESTful架构中,每一个网址代表一种资源。所有网址中不能有动词,只能用名词;通常名词往往与数据库的表相对应;因为数据库的表是记录的合集,所以名词应使用复数形式。

//正确示例
https://{api}.restful.com/api/v1/routes
https://{api}.restful.com/api/v1/services
https://{api}.restful.com/api/v1/users
//错误示例
https://{api}.restful.com/api/v1/route
https://{api}.restful.com/api/v1/getService
https://{api}.restful.com/api/v1/user/disable

问题一:

思考一个问题,实际编码中不一定都是对一个字段的简单CURD,对于复杂API该如何设计:

(1)假设一个job需要开启或关闭,该如何设计?

可以将操作变成一个字段的属性,比如job增加一个enable属性,接口如下:

//开启任务
PATCH /jobs/{jobId}
{
  "enable":true
}

//关闭任务
PATCH /jobs/{jobId}
{
  "enable":false
}

(2)假设对某个用户的某个任务进行设置,该如何设计?

可以通过用户ID先检索用户资源,再通过任务ID找该用户资源下的任务。

//示例
PUT /users/{userId}/jobs/{jobId}

(3)假设对某个用户关注或取消关注,该如何设计?

可以仿照Github的设计,将关注、点赞也看做是一种抽象的资源,从而可以看做,对某个用户的附属资源进行操作。

//关注
PUT /users/{userId}/following

//取消关注 
DELETE /users/{userId}/following

(4)假设登录、登出这种行为呢,该如何设计RESTful API?

可以考虑将登录获得的东西进行资源模拟,例如:

//登录的目的是为了创建token,所以登录可以写成如下形式
POST /token

//登出的目的是为了删除token,所以登出可以写成如下形式
DELETE /token/{token}

2.5 资源的表述

资源是数据,它可以有不同的表现形式,我们把它称为资源的表述。例如数据库中的二进制数据,用户可以根据需要获得JSON、CSV、XML、Excel等不同格式。

客户端可以通过Accept请求头指定资源的表述,服务端则通过Content-Type响应头响应返回的资源格式。

//请求
GET https://{api}.restful.com/api/v1/routes
Accept: application/json

//响应
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
   "name":"root route",
   "path":"/api/group/**",
   "to":"/api/**" 
} 

2.6 操作行为

常用的HTTP操作行为有下面五个(括号中是一般对应的SQL命令)

  • GET(SELECT):从服务器获得资源
  • POST(CREATE):在服务器新建一个资源
  • PUT(UPDATE):在服务器更新资源;在服务器更新或创建资源(客户端提供改变后的完整资源)
  • PATCH(UPDATE):在服务器更新资源(客户端提供改变的部分资源)
  • DELETE(DELETE):从服务器删除资源(也可能是逻辑删)
//获得所有路由信息
GET https://{api}.restful.com/api/v1/routes

//获得指定路由信息
GET https://{api}.restful.com/api/v1/routes/{routeId}

//获得指定服务的指定路由信息
GET https://{api}.restful.com/api/v1/services/{routeId}/routes/{routeId}

//创建一个路由信息
POST https://{api}.restful.com/api/v1/routes

//更新或创建路由信息(全部)
PUT https://{api}.restful.com/api/v1/routes

//更新路由信息(部分)
PATCH https://{api}.restful.com/api/v1/routes

//删除(也可以是逻辑删)
DELETE https://{api}.restful.com/api/v1/routes/{routeId} 

2.7 过滤

如果资源数量很多,用户可能需要过滤返回结果。

下面是一些常见参数。

  • ?pageIndex=1&pageSize=10:返回第一页,每页返回10条记录。
  • ?sortby=num&order=asc:指定结果按照那个字段排序,以及排序顺序。
  • ?type=1:获得类型是1的自数据集合

2.8 状态码

服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词)。

200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
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 - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

2.9 HATEOAS

HATEOAS又叫做Hypermedia API,超媒体API通俗理解就是,API的返回结果中包含下一步可以调用那些API。通常包括与当前API的关系、API的路径、API的描述、返回类型、请求类型。

例如:

{"link": {
  "rel":   "collection",
  "href":  "https://{api}.restful.com/api/v1/routes/{routeId}/auths",
  "title": "auths of route",
  "type":  "application/json",
  "method":"get"
}}

三、简化Restful API

3.1 状态码

我们调整和简化了Restful API状态码的返回,因为我们需要更加详细的描述异常问题。

(1)API都应使用HTTP状态码 200(OK) 响应客户端请求

(2)API都采用JSON结构请求和返回

(3)返回结果符合以下结构

{
	"success": false, //ture成功,false失败
	"code": 10000, //错误码
	"message": "", //错误描述
	"value": {} //值
}

3.2 不支持

相对于标准RESTful API,不支持以下特性:

(1)HTTP状态码

(2)HATEOAS

四、参考

Github API

Kong API

菜鸟教程-Restful

阮一峰RESTful API

RESTful API

谈对RESTful API理解

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值