美文网首页
3分钟短文:太爽了,用Laravel写API接口!

3分钟短文:太爽了,用Laravel写API接口!

作者: 程序员小助手 | 来源:发表于2020-10-18 22:06 被阅读0次

    引言

    我们一直在讲,通过路由传达到控制器,处理好数据并渲染到视图,但是对于现代的应用,
    前后端分离的情况下,后端写个接口就完事儿了。

    img

    本期为大家说一说用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',
            \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 目录下。

    用户权限

    让我们把目光还聚焦在系统默认声明的那条路由:

    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领域原创作者

    相关文章

      网友评论

          本文标题:3分钟短文:太爽了,用Laravel写API接口!

          本文链接:https://www.haomeiwen.com/subject/vbkhmktx.html