L03 第二章笔记
一、RESTful
(一)什么是 RESTful?
RESTful: Representational State Transfer,直译为表现层状态转移,或许可以解释为用 URL 定位资源,用 HTTP 动词描述操作。
(二)接口的设计原则
一套接口应该尽量满足以下几个原则:
安全可靠,高效,易扩展。
简单明了,可读性强,没有歧义。
API 风格统一,调用规则,传入参数和返回数据有统一的标准。
(三)RESTful 设计原则
(1) HTTPS。
(2) 尽可能将 API 与其主域名区分开:
- 可以使用专用域名,访问我们的 API:
https://api.larabbs.com
- 也可以放在主域名下:
https://www.larabbs.com/api
(3) 版本控制
- 将版本号直接加入 URL 中
https://api.larabbs.com/v1
https://api.larabbs.com/v2
- 使用 HTTP 请求头的 Accept 字段进行区分
https://api.larabbs.com/
Accept: application/prs.larabbs.v1+json
Accept: application/prs.larabbs.v2+json
(4) 使用 URL 定位资源
在 RESTful 的架构中,所有的一切都表示资源,每一个 URL 都代表着一种资源。(一切皆资源)
资源尽量满足以下条件:
名词的复数。
尽量不要在 URL 中使用动词。
资源的特点:
资源的设计可以嵌套,表明资源与资源之间的关系。
大部分情况下我们访问的是某个
资源集合
,想得到单个资源
可以通过资源的 id 或 number 等唯一标识获取。某些情况下,资源会是单数形式,例如某个项目某个 issue 的锁,每个 issue 只会有一把锁,所以它是单数。
错误的例子:
POST https://api.larabbs.com/createTopic
GET https://api.larabbs.com/topic/show/1
POST https://api.larabbs.com/topics/1/comments/create
POST https://api.larabbs.com/topics/1/comments/100/delete
正确的例子:
POST https://api.larabbs.com/topics
GET https://api.larabbs.com/topics/1
POST https://api.larabbs.com/topics/1/comments
DELETE https://api.larabbs.com/topics/1/comments/100
(5) 使用 HTTP 动词描述操作
前面提到,RESTful 是使用 URL 定位资源,使用 HTTP 动词来操作资源。
常见的 HTTP 动词及其描述:
动词 | 描述 |
---|---|
GET | 获取资源,单个或多个 |
POST | 创建资源 |
PUT | 更新资源,客户端提供完整的资源数据 |
PATCH | 更新资源,客户端提供部分的资源数据 |
DELETE | 删除资源 |
幂等性以后再说。
(6) 资源过滤
我们需要提供合理的参数供客户端过滤资源,例如
?state=closed: 不同状态的资源
?page=2&per_page=100:访问第几页数据,每页多少条。
?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
(7) 正确使用状态码
HTTP 提供了丰富的状态码供我们使用,正确的使用状态码可以让响应数据更具可读性。
(8) 数据响应格式
默认的数据响应格式为 JSON。
如果客户端有需求使用其他的响应格式,例如 XML,需要在 Accept 头中指定需要的格式:
https://api.larabbs.com/
Accept: application/prs.larabbs.v1+json
Accept: application/prs.larabbs.v1+xml
对于错误数据,默认使用如下结构:
'message' => ':message', // 错误的具体描述
'errors' => ':errors', // 参数的具体错误描述,422 等状态提供
'code' => ':code', // 自定义的异常码
'status_code' => ':status_code', // http状态码
'debug' => ':debug', // debug 信息,非生产环境提供
(9) 调用频率限制
为了防止服务器被攻击,减少服务器压力,需要对接口进行合适的限流控制,需要在响应头信息中加入合适的信息,告知客户端当前的限流情况:
X-RateLimit-Limit :100 最大访问次数
X-RateLimit-Remaining :93 剩余的访问次数
X-RateLimit-Reset :1513784506 到该时间点,访问次数会重置为 X-RateLimit-Limit
超过限流次数后,需要返回 429 Too Many Requests 错误。
(10) 编写文档
二、使用 Postman
三、API 基础环境
(一)测试接口
(1)在 routes/api.php
中定义测试路由:
Route::prefix('v1')->name('api.v1.')->group(function() {
Route::get('version', function() {
return 'this is version v1';
})->name('version');
});
(2)在 Postman 中访问 larabbs.test/api/v1/version
。
得到的结果为
this is version v1
如果有很多额外的 html 标签,则应该检查 Headers,并为其添加 Accept
头,值为 application/json
。
(二)Postman 的环境变量功能
使用环境变量,避免切换环境调试时,需要一个个去手动修改 api 的痛苦。
例如:由 larabbs.app 切换为 larabbs.test:
线上:
http://larabbs.app/api/v1/version
本地:
http://larabbs.test/api/v1/version
使用环境变量:
http://{{host}}/api/v1/version
步骤:
添加环境变量。
设置键与值。
在上例中,host 就是环境变量的键,需要用 {{}}
括起来,因为在 PostMan url 中,使用双括号表示变量。
(三)默认 Accept 头
Accept 头:
决定了响应返回的格式。
必须是客户端进行接口调用的时候设置。
Accept 头是如此的重要,但设置不方便(需要一个个手动设置),就会想到能不能设置默认值呢?答案是可以的:我们可以添加一个中间件,给所有的 API 路由手动设置一下。步骤如下:
(1)生成中间件 AcceptHeader
:
php artisan make:middleware AcceptHeader
(2)在中间件中给请求添加一个 Accept 的头:
...
class AcceptHeader
{
public function handle($request, Closure $next)
{
$request->headers->set('Accept', 'application/json');
return $next($request);
}
}
(3)在 app/Http/Kernel.php
的 api 中间件组中注册该中间件:
protected $middlewareGroups = [
'web' => [
.
.
.
],
'api' => [
\App\Http\Middleware\AcceptHeader::class,
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
记于 2022 年 5 月 4 日下午。
推荐文章: