• Rest Api CRUD in Laravel with Api Resources


    执行:

    php artisan make:model Task –mf

    批注 2020-04-14 030417

    执行:

    php artisan make:controller TaskController -r

    批注 2020-04-14 030434

    <?php
    
    use IlluminateDatabaseMigrationsMigration;
    use IlluminateDatabaseSchemaBlueprint;
    use IlluminateSupportFacadesSchema;
    
    class CreateTasksTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::create('tasks', function (Blueprint $table) {
                $table->id();
                $table->unsignedBigInteger('user_id');
                $table->string('title');
                $table->text('description');
                $table->dateTime('due');
                $table->timestamps();
            });
            Schema::table('tasks', function (Blueprint $table) {
                $table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete();
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('tasks');
        }
    }
    
    
    CreateTasksTable.php

    执行:

    php artisan migrate

    TaskController修改index方法:

    public function index()
    {
        //
        $tasks = Task::all();
        return response($tasks, 200);
    }
    

    api.php添加:

    Route::resource('task', ‘TaskController');
    

    然后我们用PostMan发送请求测试:

    批注 2020-04-14 133543

    因为目前我们数据库中没有添加任何数据,所以返回为空,尝试用factory添加一些数据:

    修改一下task的migration文件:

    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id');
            $table->string('title');
            $table->text('description')->nullable();
            $table->dateTime('due')->nullable();
            $table->timestamps();
        });
        Schema::table('tasks', function (Blueprint $table) {
            $table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete();
        });
    }
    

    然后执行:

    php artisan migrate:fresh

    强制删除所有数据表并重新生成。

    打开TaskFactory.php 修改如下:

    <?php
    
    /** @var IlluminateDatabaseEloquentFactory $factory */
    
    use AppTask;
    use FakerGenerator as Faker;
    
    $factory->define(Task::class, function (Faker $faker) {
        return [
            //
            'title' => $faker->company,
            'description' => $faker->paragraph(20),
            'user_id' => 1,
        ];
    });
    
    

    执行:

    php artisan passport:install

    批注 2020-04-14 134715

    然后

    批注 2020-04-14 134427

    添加用户数据后,执行

    php artisan tinker

    在tinker中执行:

    factory(AppTask::class,5)->create();

    添加5条任务数据。

    批注 2020-04-14 134858

    然后测试如下:

    批注 2020-04-14 134943

    改进:

    一个用户只能查看属于自己的任务。

    所以先定义User模型与Task模型之间的关系:

    User.php中添加:

    public function tasks()
    {
        return $this->hasMany(Task::class);
    }
    

    Task.php中添加:

    public function user()
    {
        return $this->belongsTo(User::class);
    }
    

    完善Task.php:

    添加

    protected $fillable = ['user_id', 'title', 'description', 'due'];


    terminal中键入exit退出tinker控制台。

    批注 2020-04-14 135741

    执行:

    参考资料:API 资源

    从本质上来说,资源的作用很简单。它们只需要将一个给定的模型转换成一个数组。所以每一个资源都包含一个 toArray 方法用来将你的模型属性转换成一个可以返回给用户的 API 友好数组

    php artisan make:resource TaskResource

    批注 2020-04-14 135722

    修改api.php:

    将之前的

    Route::resource('task', ‘TaskController');
    

    修改为

    Route::apiResource('tasks', 'TaskController')->middleware('auth:api');

    修改TaskController的index方法如下:

    public function index()
    {
        //
        $tasks = TaskResource::collection(auth()->user()->tasks()->latest()->paginate(4));
        return response($tasks, 200);
    }
    

    现在我们需要先登录,获取用户token

    批注 2020-04-14 141052

    然后用这个token放置于authorization中,

    批注 2020-04-14 141254

    然后发送请求获取属于user的对应的全部task资源数据。

    如果没有这个token会显示:

    批注 2020-04-14 141349

    接下来完善store方法,注意我们是api方式所以不需要几个show form方法:

    批注 2020-04-14 141745批注 2020-04-14 141829

    删除掉就行。

    创建资源前需要验证,然后验证用户通过模型关联创建task即可,最后返回一个taskresource实例。

    public function store(Request $request)
    {
        $validated = Validator::make($request->all(), [
            'title' => 'required|max:255',
        ]);
        if ($validated->fails()) {
            return response($validated->errors()->all());
        }
        $task = auth()->user()->tasks()->create($request->all());
    
        return new TaskResource($task->load('user'));
    }
    
    

    最后返回的时候,我们用了load方法,这里不能用with,具体区别在于with是一次,load是分开,因为我们先获取生成的task,所以是分开的,只能用load。

    PostMan测试如下:

    Token我们已经登录后然后配置了:

    批注 2020-04-14 144140

    发送请求:

    批注 2020-04-14 144530

    show方法修改如下:

    批注 2020-04-14 144826

    postman测试:

    批注 2020-04-14 144911

    update方法:

    public function update(Request $request, Task $task)
    {
        //
        $validated = Validator::make($request->all(), [
            'title' => 'required|max:255',
        ]);
        if ($validated->fails()) {
            return response($validated->errors()->all());
        }
    
        if (!auth()->user()->tasks->contains($task)) {
            return response('No permission!', 422);
        }
    
        $task->update($request->all());
    
        return new TaskResource($task->load('user'));
    
    }
    

    Postman测试:

    批注 2020-04-14 145920

    或发送:

    批注 2020-04-14 151154

    数据库查看结果:

    批注 2020-04-14 145951

    在destroy方法之前我们还是给模型添加一个软删除的支持,

    批注 2020-04-14 150155

    批注 2020-04-14 150214

    以及对应的migrate添加:

    批注 2020-04-14 150528

    <?php
    
    use IlluminateDatabaseMigrationsMigration;
    use IlluminateDatabaseSchemaBlueprint;
    use IlluminateSupportFacadesSchema;
    
    class AddSoftdeteleToUsersTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::table('users', function (Blueprint $table) {
                //
                $table->softDeletes();
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::table('users', function (Blueprint $table) {
                //
                $table->dropSoftDeletes();
            });
        }
    }
    
    

    批注 2020-04-14 150609

    <?php
    
    use IlluminateDatabaseMigrationsMigration;
    use IlluminateDatabaseSchemaBlueprint;
    use IlluminateSupportFacadesSchema;
    
    class AddSoftdeteleToTasksTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::table('tasks', function (Blueprint $table) {
                //
                $table->softDeletes();
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::table('tasks', function (Blueprint $table) {
                //
                $table->dropSoftDeletes();
            });
        }
    }
    
    

    执行:

    php artisan migrate

    批注 2020-04-14 150922

    destory方法:

    public function destroy(Task $task)
    {
        //
        if (!auth()->user()->tasks->contains($task)) {
            return response('No permission!', 422);
        }
        $task->delete();
    
        return response(['message' => 'Success deleted!']);
    }
    

    最后Postman测试结果:

    批注 2020-04-14 150848

    数据库结果:

    批注 2020-04-14 151034

    due修正后:

    store方法:

    public function store(Request $request)
    {
        $validated = Validator::make($request->all(), [
            'title' => 'required|max:255',
        ]);
        if ($validated->fails()) {
            return response($validated->errors()->all());
        }
        $input = $request->all();
        if ($request->has('due')) {
            $input['due'] = Carbon::parse($request->get('due'))->toDateTimeString();
        }
        $task = auth()->user()->tasks()->create($input);
    
        return new TaskResource($task->load('user'));
    }
    

    update方法:

    public function update(Request $request, Task $task)
    {
        //
        $validated = Validator::make($request->all(), [
            'title' => 'required|max:255',
        ]);
        if ($validated->fails()) {
            return response($validated->errors()->all());
        }
    
        if (!auth()->user()->tasks->contains($task)) {
            return response('No permission!', 422);
        }
        $input = $request->all();
    
        if ($request->has('due')) {
            $input['due'] = Carbon::parse($request->get('due'))->toDateTimeString();
        }
        $task->update($input);
    
        return new TaskResource($task->load('user'));
    
    }
    
    

    PostMan测试结果:

    批注 2020-04-14 152044

    以及:

    批注 2020-04-14 152504

    数据库查看:

    批注 2020-04-14 152557

  • 相关阅读:
    PHP+MySQL
    Appstore排名前十的程序员应用软件
    架构师的平凡之路
    程序员,如何三十而立?
    不懂技术也可以轻松开发一款APP
    php语法学习:轻松看懂PHP语言
    你真的了解软件测试行业吗?
    十个程序员必备的网站推荐
    从更高点看软件开发的侧重点
    php如何实现文件下载
  • 原文地址:https://www.cnblogs.com/dzkjz/p/12695458.html
Copyright © 2020-2023  润新知