Laravel開発：３．APIの作成

こちらの内容は[ブログ](https://ksysnote.com/php/laravel-api/)にアップしています。

<h3>はじめに</h3>
https://ksysnote.com/php/laravel-auth-voyager/

こちらの続きとなっています。

今回はLaravelで簡単にAPIを作ってみようと思います。またSeederを使用して簡単なサンプルデータを作成しています。
<h4>環境：</h4>
OS : macOS High Sierra 10.13.6

MAMP : 5.1

Laravel : 5.7.6
<h3>データの作成</h3>
<h4>マイグレーションファイルの作成</h4>
予定のデータとして「task」テーブルを作成していきます。
<pre class="EnlighterJSRAW" data-enlighter-language="null">$ php artisan make:migration create_tasks_table --create=tasks</pre>
「/database/migrations/DATETIME_create_tasks_table.php」を編集します。
<pre class="EnlighterJSRAW" data-enlighter-language="null">public function up()
{
    Schema::create('tasks', function (Blueprint $table) {
        $table-&gt;increments('id');
        $table-&gt;string('name');         // 追加
        $table-&gt;text('description');    // 追加
        $table-&gt;integer('client_id');   // 追加
        $table-&gt;timestamps();
    });
}

</pre>
<h4>モデルを作成する</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="null">$ php artisan make:model Task</pre>
<h3>マイグレーションの実行</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="null">$ php artisan migrate</pre>
<h3>サンプルデータの作成</h3>
<h4>Seederを作成する</h4>
初期データを作成するために「seeder」を使用する
<pre class="EnlighterJSRAW" data-enlighter-language="null">$ php artisan make:seeder ClientsTableSeeder
$ php artisan make:seeder TasksTableSeeder</pre>
「/database/seeds/ClientsTableSeeder.php」
<pre class="EnlighterJSRAW" data-enlighter-language="null">public function run()
{
    factory(App\Client::class, 50)-&gt;create();
}
</pre>
「/database/seeds/TasksTableSeeder.php」
<pre class="EnlighterJSRAW" data-enlighter-language="null">public function run()
{
    factory(App\Task::class, 50)-&gt;create();
}</pre>
「/database/seeds/DatabaseSeeder.php」
<pre class="EnlighterJSRAW" data-enlighter-language="null">public function run()
{
    $this-&gt;call(ClientsTableSeeder::class);
    $this-&gt;call(TasksTableSeeder::class);
}</pre>
Seederを実行すると、「ClientsTableSeeder.php」と「TasksTableSeeder.php」を実行して50件のサンプルデータを作成することができるようになりました。
<h4>Model Factoryを作成する</h4>
ModelFactoryで「Faker」を使用して、それらしくサンプルデータを作成します。
<pre class="EnlighterJSRAW" data-enlighter-language="null">$ php artisan make:factory ClientFactory
$ php artisan make:factory TaskFactory</pre>
「/database/factories/ClientFactory.php」
<pre class="EnlighterJSRAW" data-enlighter-language="null">&lt;?php
// app/database/factories/UserFactory.php
use Faker\Generator as Faker;
 
$factory-&gt;define(App\Client::class, function (Faker $faker) {
    static $password;
    return [
        'name' =&gt; $faker-&gt;name,
        'email' =&gt; $faker-&gt;unique()-&gt;safeEmail,
        'password' =&gt; $password ?: $password = bcrypt('secret'),
        'remember_token' =&gt; str_random(10),
    ];
});</pre>
「/database/factories/TaskFactory.php」
<pre class="EnlighterJSRAW" data-enlighter-language="null">&lt;?php
// app/database/factories/TaskFactory.php
use Faker\Generator as Faker;
$factory-&gt;define(App\Task::class, function (Faker $faker) {
    $clients = App\Client::pluck('id')-&gt;toArray();
    return [
        'name' =&gt; $faker-&gt;unique()-&gt;name,
        'description' =&gt; $faker-&gt;realText(200),
        'client_id' =&gt; $faker-&gt;randomElement($clients)
    ];
});</pre>
<h4>日本語に設定する</h4>
このままだと英語のサンプルデータになるので日本語設定にします

「/config/app.php」に追記します
<pre class="EnlighterJSRAW" data-enlighter-language="null">'faker_locale' =&gt; env('DEV_FAKER_LOCALE', 'en_US'),</pre>
「/.env」に追記します。
<pre class="EnlighterJSRAW" data-enlighter-language="null">DEV_FAKER_LOCALE=ja_JP</pre>
<h4>Seederを実行する</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="null">$ php artisan db:seed</pre>
<h4>確認</h4>
管理画面からサンプルデータが作成されていることを確認します。
<p id="MSCAJdt"><img class="alignnone size-full wp-image-92 " src="https://ksysnote.com/wp-content/uploads/2018/10/img_5bb1b83071459.png" alt="" /></p>
<p id="ryTbZHT"><img class="alignnone size-full wp-image-94 " src="https://ksysnote.com/wp-content/uploads/2018/10/img_5bb1b88fc671c.png" alt="" /></p>

<h3>コントローラの作成</h3>
<h4>Taskのリソースを作成する</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="null">$ php artisan make:resource Task</pre>
「/app/Http/Resources/Task.php」を編集する
<pre class="EnlighterJSRAW" data-enlighter-language="null">public function toArray($request)
{
    return [
        'id' =&gt; $this-&gt;id,
        'task' =&gt; $this-&gt;name,
        'task_description' =&gt; $this-&gt;description
    ];
}
</pre>
<h4>TaskContorllerを作成する</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="null">$ php artisan make:controller TaskController</pre>
「/app/Http/Controllers/TaskController.php」を編集する
<pre class="EnlighterJSRAW" data-enlighter-language="null">&lt;?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Resources;
use App\Task;
use App\Http\Resources\Task as TaskResource;

class TaskController extends Controller
{
    public function index()
    {
        //Get all task
        $tasks = Task::paginate(15);

        // Return a collection of $task with pagination
        return TaskResource::collection($tasks);
    }

    public function show($id)
    {
        //Get the task
        $task = Task::findOrfail($id);

        // Return a single task
        return new TaskResource($task);
    }

    public function destroy($id)
    {
        //Get the task
        $task = Task::findOrfail($id);

        if($task-&gt;delete()) {
            return new TaskResource($task);
        }

    }

    public function store(Request $request)  {

        $task = $request-&gt;isMethod('put') ? Task::findOrFail($request-&gt;task_id) : new Task;

        $task-&gt;id = $request-&gt;input('task_id');
        $task-&gt;name = $request-&gt;input('name');
        $task-&gt;description = $request-&gt;input('description');
        $task-&gt;user_id =  1; //$request-&gt;user()-&gt;id;

        if($task-&gt;save()) {
            return new TaskResource($task);
        }

    }
}
</pre>
<h4>ルーティングの設定</h4>
「/routes/api.php」
<pre class="EnlighterJSRAW" data-enlighter-language="null">// get list of tasks
Route::get('tasks','TaskController@index');
// get specific task
Route::get('task/{id}','TaskController@show');
// create new task
Route::post('task','TaskController@store');
// update existing task
Route::put('task','TaskController@store');
// delete a task
Route::delete('task/{id}','TaskController@destroy');
</pre>
<h4>確認</h4>
postmanでAPIの動作を確認してみます。

「http://localhost:8888/api/tasks」
<p id="lWgkjQD"><img class="alignnone size-full wp-image-95 " src="https://ksysnote.com/wp-content/uploads/2018/10/img_5bb1bd5508d62.png" alt="" /></p>

<h3>参考</h3>
https://arjunphp.com/how-to-create-restful-api-in-laravel-5-7/

https://gomiba.co.in/blog/archives/1365

https://www.ritolab.com/entry/28#aj_4