3分钟短文:太爽了,用Laravel写API接口!
引言
我们一直在讲,通过路由传达到控制器,处理好数据并渲染到视图,但是对于现代的应用, 前后端分离的情况下,后端写个接口就完事儿了。
本期为大家说一说用laravel写restful风格的API,看看能有多简单。
以路由开端
写API接口,与传统的渲染前端模板页面有什么区别?少了视图,只需要准备好数据, 并按照规则格式化,返回就可以了。
laravel默认的api接口路由在 routes/api.php 文件内定义,默认的情况下预定义了一个资源类型的api接口,代码如下:
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
调用了 auth:api 中间件用于验证用户的授权,如果授权通过,声明的get方法获取用户的信息,并返回 User 模型。这在之前的章节是很常见的操作,我们不做赘述了。
那么这个路由文件,是什么时候加载上去的呢?在文件 app/Providers/RouteServiceProvider.php 内,看这样一段:
protected function mapApiRoutes()
{
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
该服务提供者声明路由使用 api 字符前缀,并调用 api 中间件,该中间件定义在 app/Http/Kernel.php 文件内:
protected $middlewareGroups = [
'api' => [
'throttle:60,1',
IlluminateRoutingMiddlewareSubstituteBindings::class,
],
];
至于命名空间 $this->namespace 一般返回 AppHttpControllers,我们为了区分API与其他应用,在目录 app/Http/Controller 下创建 API 目录,用于存储所有API相关的控制器。
那么上述的 RouteServiceProvider.php 文件内 mapApiRoutes 方法内的 namespace 需要这样写:
->namespace($this->namespace . 'API')
仍然以 Event 模型作为示例,在 routes/api.php 文件内声明一个资源类型的路由:
Route::resource('/events', 'APIEventsController');
注意命名空间上多出来的前缀 API ,这说明我们是把 EventController 文件放在了 API 目录下。
用户权限
让我们把目光还聚焦在系统默认声明的那条路由:
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
注意中间件 auth:api,因为api请求是无状态的,每次请求之间没有任何关联,所以使用用户权限区分资源的返回。那么我们怎么拿到用户授权呢?这在 config/auth.php 文件内定义,看系统自带的这一段配置代码:
'guards' => [
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
这一段定义了我们使用何种方式认证用户的身份。默认的驱动 token 定义在框架文件 laravel/framework/src/Illuminate/Auth/TokenGuard.php 内。长话短说,默认构造类传入的字段如下:
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 函数:
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('api_token', 60)->unique();
});
}
还有回滚使用的 down 方法:
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 字符串,
{
"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 属性的定义:
protected $hidden = [
'password', 'remember_token',
];
这些字段都对对外不公开访问。
写在最后
本文介绍了如何声明api地址,已经解释了api从中间件到路由的由来,明白了api授权的方式,可以为我们更灵活地定制授权方式提供便利。这在laravel内都是可插拔的,替换为我们的逻辑代码就可以愉快工作了。
Happy coding :-)
我是@程序员小助手,专注编程知识,圈子动态的IT领域原创作者
- 利用腾讯云COS云对象存储定时远程备份网站
- 分享一个自写的Python远程命令和文件(夹)传输类
- Oracle数据误操作全面恢复实战(r11笔记第78天)
- 远程协助解决异常宕库的问题(r11笔记第75天)
- Nginx-helper纯代码版,文章评论发布自动清理Fastcgi缓存
- MySQL和Oracle行值表达式对比(r11笔记第74天)
- 闪回数据库不是“万金油”(r11笔记第73天)
- 修改Apache的超时设置,解决长连接请求超时问题
- Oracle 12cR2初体验(r11笔记第91天)
- MySQL中的undo截断(r11笔记第89天)
- Linux系统 df 命令显示异常、分区丢失问题解决
- MySQL主从、字典死锁、连接数的Python监控脚本
- MySQL Online DDL(二)(r11笔记第88天)
- 转-Android上面运行golang
- php概述
- php教程
- php环境搭建
- PHP书写格式
- php变量
- php常量
- PHP注释
- php数组
- php字符串 string
- PHP整型 integer
- PHP浮点型 float
- php布尔型
- php数据类型之数组
- php数据类型之对象
- php数据类型之null
- php数据类型之间的转换
- php运算符
- php表达式
- PHP循环控制
- PHP流程控制
- php函数
- php全局变量
- PHP魔术变量
- php命名空间
- php 日期
- PHP包含文件
- php文件
- PHP 文件上传
- php Cookies
- php Sessions
- php email
- php安全email
- php错误处理
- PHP异常处理
- php过滤器
- PHP 高级过滤器
- php json
- php 表单
- PHP MySQL 简介
- PHP 连接 MySQL
- php创建数据库
- php 创建表
- php mysq 插入数据
- PHP MySQL 插入多条数据
- PHP MySQL 预处理语句
- php mysql 读取数据
- php mysql where
- PHP MySQL Order By
- PHP MySQL Update
- PHP MySQL Delete
- php ODBC
- Android中Fragment相互切换间不被回收的实现方法
- Android手机管理工具类详解
- 通过代码学Sutton强化学习第四章动态规划
- android通过okhttpClient下载网页内容的实例代码
- Android自定义键盘的实现(数字键盘和字母键盘)
- Android iconify 使用详解
- XRecyclerView实现下拉刷新、滚动到底部加载更多等功能
- 浅析Android 快速实现图片压缩与上传功能
- Android处理时间各种方法汇总
- Android TextView Marquee的应用实例详解
- Android毛玻璃背景效果简单实现代码
- ClickHouse和他的朋友们(3)MySQL Protocol和Write调用栈
- ubuntu安装多个版本的CUDA并随时切换
- 如何在Ubuntu 18.04(实体机)上配置OpenWRT的开发环境
- Android 组合控件实现布局的复用的方法