API接口如同契约。接口并不包含任何代码实现,只是定义了一个实现该接口的对象必须实现的一系列方法。如果一个对象实现了一个接口,那么我们就能保证这个接口所定义的一系列方法都能在这个对象上调用。由于有接口契约保证特定方法的实现,通过多态也能使类型安全的语言变得更灵活。
本文就给大家分享一下如何用laravel写restful风格的API接口,简单且实用。
以路由开端
写API接口,与传统的渲染前端模板页面有什么区别?少了视图,只需要准备好数据, 并按照规则格式化,返回就可以了。
laravel默认的api接口路由在 routes/api.php 文件内定义,默认的情况下预定义了一个资源类型的api接口,代码如下:
1 2 3 4 5 | Route::middleware( 'auth:api' )->get( '/user' , function (Request $request ) { return $request ->user(); }); |
调用了 auth:api 中间件用于验证用户的授权,如果授权通过,声明的get方法获取用户的信息,并返回 User 模型。这在之前的章节是很常见的操作,我们不做赘述了。
那么这个路由文件,是什么时候加载上去的呢?在文件 app/Providers/RouteServiceProvider.php 内,看这样一段:
1 2 3 4 5 6 7 8 9 10 11 12 13 | protected function mapApiRoutes() { Route::prefix( 'api' ) ->middleware( 'api' ) ->namespace( $this ->namespace) ->group(base_path( 'routes/api.php' )); } |
该服务提供者声明路由使用 api 字符前缀,并调用 api 中间件,该中间件定义在 app/Http/Kernel.php 文件内:
1 2 3 4 5 6 7 8 9 10 11 | protected $middlewareGroups = [ 'api' => [ 'throttle:60,1' , \Illuminate\Routing\Middleware\SubstituteBindings:: class , ], ]; |
至于命名空间 $this->namespace 一般返回 App\Http\Controllers,我们为了区分API与其他应用,在目录 app/Http/Controller 下创建 API 目录,用于存储所有API相关的控制器。
那么上述的 RouteServiceProvider.php 文件内 mapApiRoutes 方法内的 namespace 需要这样写:
->namespace($this->namespace . '\API')
仍然以 Event 模型作为示例,在 routes/api.php 文件内声明一个资源类型的路由:
Route::resource('/events', 'API\EventsController');
注意命名空间上多出来的前缀 API\ ,这说明我们是把 EventController 文件放在了 API 目录下。
用户权限
让我们把目光还聚焦在系统默认声明的那条路由:
1 2 3 4 5 | Route::middleware( 'auth:api' )->get( '/user' , function (Request $request ) { return $request ->user(); }); |
注意中间件 auth:api,因为api请求是无状态的,每次请求之间没有任何关联,所以使用用户权限区分资源的返回。那么我们怎么拿到用户授权呢?这在 config/auth.php 文件内定义,看系统自带的这一段配置代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 'guards' => [ 'api' => [ 'driver' => 'token' , 'provider' => 'users' , 'hash' => false, ], ], |
这一段定义了我们使用何种方式认证用户的身份。默认的驱动 token 定义在框架文件 laravel/framework/src/Illuminate/Auth/TokenGuard.php 内。长话短说,默认构造类传入的字段如下:
1 2 3 4 5 6 7 8 9 | UserProvider $provider , Request $request , $inputKey = 'api_token' , $storageKey = 'api_token' , $hash = false |
简单说,就是使用 users 表的 api_token 字段用户鉴权。那么默认我们 users 表显然缺少一个这样的字段,现在使用迁移文件补上:
php artisan make:migration add_api_token_field_to_users_table --table=users
首先是迁移方法 up 函数:
1 2 3 4 5 6 7 8 9 10 11 | public function up() { Schema::table( 'users' , function (Blueprint $table ) { $table ->string( 'api_token' , 60)->unique(); }); } |
还有回滚使用的 down 方法:
1 2 3 4 5 6 7 8 9 10 11 | public function down() { Schema::table( 'users' , function (Blueprint $table ) { $table ->dropColumn( 'api_token' ); }); } |
这些都是常规操作,我们在之前的章节,使用了N多次了。执行指令迁移数据库:
php artisan migrate
看看效果
准备好了路由,而且路由内声明了一个get方法返回用户模型数据。也准备好了数据库表字段 api_token。我们在数据库表内找到一个用户数据,把api_token值设置为 1234,用于测试。
现在在浏览器内请求类似如下的url地址:
http://www.example.com/api/user?api_token=1234
如无异常,顺利会输出一个 json 字符串,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | { "id" :1, "provider" :null, "provider_id" :null, "first_name" : "Tom" , "last_name" : "Hanks" , "email" : "tom@admin.com" , "city" : "" , "state_id" :null, "zip" : "43016" , "lat" :null, "lng" :null, "timezone" : "America\/New_York" , "title" : "Laravel Developer" , "created_at" : "2020-10-14 17:46:19" , "updated_at" : "2020-10-14 17:46:20" , "last_login_at" :null, "is_admin" :0, "api_token" : "1234" } |
这个json格式的数据是怎么来的呢?是在路由内,$request->user() 方法返回的User模型,使用 toArray() 格式化方法获得的。为了演示,很多字段与实际可能有所出入。
特别需要注意的是,关键的密码字段,以及 token 字段,是默认隐藏的,这得益于 User 模型内 $hiden 属性的定义:
1 2 3 4 5 | protected $hidden = [ 'password' , 'remember_token' , ]; |
这些字段都对对外不公开访问。
以上就是“用laravel写restful风格的API接口”的详细内容,不仅介绍了API从中间件到路由的由来,还明白了API授权方式,为我们日常工作提供了巨大的便利!想要了解更多关于laravel教程欢迎关注编程学习网。
扫码二维码 获取免费视频学习资料
- 本文固定链接: http://phpxs.com/post/8358/
- 转载请注明:转载必须在正文中标注并保留原文链接
- 扫码: 扫上方二维码获取免费视频资料