使用 Dingo API 快速构建 RESTful API(二)—— 编写第一个 API 接口
在一些英文文档中,我们经常会看到类似 API Endpoint 这样的术语,其实,Endpoint 就是路由的另一种表述,当我们讨论 API 时,很多人习惯将访问的 API 路由看作 Endpoint。
版本分组
为了避免和 Laravel 主应用的路由混在一起,Dingo API 使用了自己的路由器,正因如此,我们首先需要获取对应的 API 路由器实例来创建 Endpoint(可以在 routes/api.php
中定义基于 Dingo 路由器的 API 路由):
$api = app(\Dingo\Api\Routing\Router::class);
接下来需要定义 API 的版本分组,从而支持为多版本 API 接口创建同样的 Endpoint 以便后续回滚:
$api->version('v1', function ($api) {
});
如果你想要某个分组能够同时响应多个版本的 API 接口,可以传递包含多个版本号的数组到该分组:
$api->version(['v1', 'v2'], function ($api) {
});
这里基于版本号实现的分组可以看作和 Laravel 框架提供的标准路由分组一样,支持传递数组属性作为第二个参数,在这个属性数组参数中,你可以传递应用到该分组的中间件、命名空间、子域名、路由前缀等信息:
$api->version('v1', ['middleware' => 'foo'], function ($api) {
});
还可以嵌套普通的路由分组到版本分组中,以便后续实现更复杂的自定义 API Endpoint:
$api->version('v1', function ($api) {
$api->group(['middleware' => 'foo'], function ($api) {
// Endpoints registered here will have the "foo" middleware applied.
});
});
创建 API 路由
有了版本号之后就可以开始使用 $api
创建 Endpoint 了:
$api->version('v1', function ($api) {
$api->get('/task/{id}', function ($id) {
return \App\Task::findOrFail($id);
});
});
学院君注:这里我们基于之前构建的待办任务项目为基础进行演示。
因为 Endpoint 基于版本号进行分组,所以你可以使用同样的 URI 为同一 Endpoint 创建不同的响应:
$api->version('v1', function ($api) {
$api->get('/task/{id}', function ($id) {
return \App\Task::findOrFail($id);
});
});
$api->version('v2', function ($api) {
$api->get('/task/{id}', function ($id) {
return \App\Task::findOrFail($id);
});
});
在访问 Dingo API 路由之前,我们需要为其配置子域名或路由前缀,这里我们配置路由前缀为 dingoapi
,在 .env
中添加如下配置项即可:
API_PREFIX=dingoapi
然后,我们就可以通过执行 php artisan api:routes
命令看到对应的 Dingo API 路由了:
另外还有一点需要注意的是在 Dingo API 中,如果基于控制器方法定义 API 路由,需要指定完整的控制器命名空间:
$api->get('/task/{id}', \App\Http\Controllers\TaskController::class.'@show');
因为 Dingo 使用的是独立的 API 路由器,与 Laravel 内置的路由定义处理机制不同。
访问 API 路由
要访问 Dingo API,一般不会在浏览器中直接访问,因为版本号信息需要在 HTTP 请求头中指定,而不是作为 URI 的一部分,我们可以通过 Postman 来模拟 API 接口的访问:
我们在 HTTP 请求头中通过 Accept
字段指定 API 接口对应的响应实体格式及 API 版本信息,但是这里并没有显示指定,Dingo 会使用默认的 v1
作为版本号,如果完整指定的话,这里的 Accept 字段值格式如下:
Accept: application/API_STANDARDS_TREE.API_SUBTYPE.API_VERSION+json
API_STANDARDS_TREE
配置值默认为 x
,API_SUBTYPE
默认值为空字符串,所以,如果要访问版本号为 v2
的 Dingo API 接口的话,可以这么指定 Accept 请求头:
学院君注:Dingo API 通过
API_STANDARDS_TREE
、API_SUBTYPE
、API_VERSION
这三个字段来完整确定指定 API 的版本号,关于这三个字段可以参考上篇教程配置部分的介绍。
如果是在服务器上通过命令行访问,可以通过如下 curl
命令实现:
curl -v -H "Accept: application/x..v1+json" http://todo.test/dingoapi/task/1
对应接口返回数据如下:
命名路由 & 生成 URL
命名路由可以帮助我们轻松生成指定路由对应的 URL。在 Dingo API 中,你可以像在 Laravel 框架中一样命名路由:
$api->version('v1', function ($api) {
$api->get('/task/{id}', function ($id) {
return \App\Task::findOrFail($id);
})->name('task.detail');
});
然后就可以通过如下方式生成该路由对应的 URL:
$url = app(\Dingo\Api\Routing\UrlGenerator::class)
->version('v1')
->route('task.detail', ['id' => $id]);
必须提供一个版本号以便 URL 可以基于该版本号生成,同时,你可以在不同版本号中使用同一个命名路由。
No Comments