Laravel

Laravel を覚える➓ Restful API作成

Restful API

まずは以下のコマンドでrestapipjというプロジェクトを作成します。

composer create-project "laravel/laravel=8.*" restapipj --prefer-dist

次にMySQLにてrestapipjというデータベースを以下のコマンドで作成してください。

CREATE DATABASE restapipj;

次にデータベースの接続設定を行うために.envファイルを以下のように修正します。

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=restapipj
DB_USERNAME=root
DB_PASSWORD=root

次にマイグレーションファイルを作成します。
ターミナルからrestapipjディレクトリで以下のコマンドを実行します。

php artisan make:migration create_rests_table

マイグレーションファイルの記述

では、作成されたマイグレーションファイルのスクリプトを記述しましょう。
xxxx_create_rests_table.phpを開き、以下のように内容を記述して下さい。

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateRestsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('rests', function (Blueprint $table) {
            $table->id();
            $table->string('message');
            $table->string('url');
            $table->timestamp('created_at')->useCurrent()->nullable();
            $table->timestamp('updated_at')->useCurrent()->nullable();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('rests');
    }
}


マイグレーションクラスでは、upでテーブル生成の処理、downでテーブル削除の処理をするのが基本でした。
テーブルの作成は既に何度か行いましたが、Schema::createというメソッドを使って行います。
この第2引数に指定したクロージャ内で、$tableのメソッドを呼び出してフィールドを設定していきます。
downメソッドは、Schema:droplfexistsでテーブルを削除するようにしてあります。

マイグレーションの実行

では、マイグレーションを実行しましょう。
コマンドプロンプトまたはターミナルからrestapipjディレクトリで以下のコマンドを実行しましょう。

php artisan migrate

モデルの作成

ダミーとしていくつかレコードを用意しておく必要があります。
シードを作成する前に、モデルを作りましょう。
コマンドプロンプトまたはターミナルからrestapipjディレクトリで以下のコマンドを実行しましょう。

php artisan make:model Rest


これで、「Rest.php」というファイルがapp>Modelsフォルダ内に作成されます。
これが、今回のrestsテーブルを扱うモデルとなります。

Restモデルの記述

では、作成されたRest.phpを開き、スクリプトを記述しましょう。
以下のように内容を書き換えて下さい。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Rest extends Model
{
    use HasFactory;

    protected $guarded = array('id');

    public static $rules = array(
        'message' => 'required',
        'url' => 'required'
    );
}

シードの作成

では、シードを用意しましょう。
まずはシーダーファイルを作ります。
コマンドプロンプトまたはターミナルからrestapipjディレクトリで以下のコマンドを実行しましょう。

php artisan make:seeder RestsTableSeeder


これで、「database」内の「seeders」フォルダ内に「RestsTableSeeder.php」というファイルが作成されます。

RestsTableSeeder の記述

では、作成されたシーダーファイルを記述しましょう。
RestsTableSeeder.phpを開き、以下のように記述しておきましょう。

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\Rest;

class RestsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $param = [
            'message' => 'test1',
            'url' => 'test1@example.com'
        ];
        $rest = new Rest;
        $rest->fill($param)->save();
        $param = [
            'message' => 'test2',
            'url' => 'test2@example.com'
        ];
        $rest = new Rest;
        $rest->fill($param)->save();
        $param = [
            'message' => 'test3',
            'url' => 'test3@example.com'
        ];
        $rest = new Rest;
        $rest->fill($param)->save();
    }
}


ここでは、ダミーとして3つのレコードを保存するようにしてあります。
今回は、DBクラスではなく、先ほど作成したRestモデルクラスを使ってレコードを作成しています。
まず、保存する値を連想配列にまとめておき、new Restでインスタンスを作成後、fillで連想配列の値を適用します。
そして、saveで保存すれば作業完了です。

DatabaseSeederの登録

作成したRestsTableSeederクラスは、DatabaseSeederに登録をしておかないといけません。
では、「seeders」内にある「DatabaseSeeder.php」を開き、以下のように修正して下さい。

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(RestsTableSeeder::class);
    }
}


これで、シードの実行時にRestsTableSeederのrunが呼び出され、実行されるようになります。

シードの実行

コマンドプロンプトまたはターミナルからrestapipjディレクトリで以下のコマンドを実行しましょう。

php artisan db:seed


RestsTableSeederのrunが実行され、用意しておいた3つのダミーレコードがテーブルに登録されます。
これで、データベース関連の準備は完了です。

RESTコントローラの作成

では、作成されたRestモデルを利用したRESTfulサービスを作成しましょう。
サービスは、普通のWebアプリと同様、コントローラを作成して作ります。
コマンドプロンプトまたはターミナルからrestapipjディレクトリで以下のコマンドを実行しましょう。

php artisan make:controller RestController --api --model=Rest


これで、「Http」内の「Controllers」フォルダ内に「RestController.php」というファイルが作成されます。
今回、コントローラを作成する際に「--api」というオプションを追記しました。
これは、APIリソースルートとしてコントローラにメソッド類を追記しておくためのものです。
通常、コントローラでは1つ1つの機能をメソッドとして用意し、そのルート情報を1つずつ記述していきます。
しかし、APIリソースルートとして登録すると、CRUD関連のアクセスがすべて一括して使えるようになる変わりに、アクセスするアドレスやアクションメソッドは最初から決められた形になります。
また一式まとめて作成されるため、それらのメソッドは最初から全て作成しておく必要があります。

APIリソースルートについて

作成されたRestController.phpを見てみましょう。
これは、デフォルトでいくつものメソッドが用意されています。
全スクリプトを挙げておくと以下のようになります。

<?php

namespace App\Http\Controllers;

use App\Models\Rest;
use Illuminate\Http\Request;

class RestController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }
    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }
    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Rest  $rest
     * @return \Illuminate\Http\Response
     */
    public function show(Rest $rest)
    {
        //
    }
    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Rest  $rest
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Rest $rest)
    {
        //
    }
    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Rest  $rest
     * @return \Illuminate\Http\Response
     */
    public function destroy(Rest $rest)
    {
        //
    }
}

アクションメソッドを作成する

コントローラのアクションメソッドを使ってみましょう。
app/Http/Controllers/RestController.phpを参照してください。

<?php

namespace App\Http\Controllers;

use App\Models\Rest;
use Illuminate\Http\Request;

class RestController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $items = Rest::all();
        return response()->json([
            'data' => $items
        ], 200);
    }
    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $item = Rest::create($request->all());
        return response()->json([
            'data' => $item
        ], 201);
    }
    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Rest  $rest
     * @return \Illuminate\Http\Response
     */
    public function show(Rest $rest)
    {
        $item = Rest::find($rest);
        if ($item) {
            return response()->json([
                'data' => $item
            ], 200);
        } else {
            return response()->json([
                'message' => 'Not found',
            ], 404);
        }
    }
    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Rest  $rest
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Rest $rest)
    {
        $update = [
            'message' => $request->message,
            'url' => $request->url
        ];
        $item = Rest::where('id', $rest->id)->update($update);
        if ($item) {
            return response()->json([
                'message' => 'Updated successfully',
            ], 200);
        } else {
            return response()->json([
                'message' => 'Not found',
            ], 404);
        }
    }
    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Rest  $rest
     * @return \Illuminate\Http\Response
     */
    public function destroy(Rest $rest)
    {
        $item = Rest::where('id', $rest->id)->delete();
        if ($item) {
            return response()->json([
                'message' => 'Deleted successfully',
            ], 200);
        } else {
            return response()->json([
                'message' => 'Not found',
            ], 404);
        }
    }
}


ここでそれぞれのアクションについて解説します。

index

まずは全データを取得するためのGETメソッドを用意します。
indexの部分に記述していきます。

$items = Rest::all();
return response()->json([
    'data' => $items
], 200);


$items = Rest::all(); return response()->json([ 'data' => $items ], 200);

Eloquentを利用することでDBではなくRest(モデル名)と記述できます。
モデル名::all()」で全データを取得できます。

APIはレスポンスとしてJSON形式のデータをフロントエンドに返すのでjsonを利用します。
第一引数にメッセージ、第二引数にステータスコードを指定します。
今回の場合、第一引数に取得した全てのデータ第二引数に200という成功を表すステータスコードを使用しています。

store

次にデータを追加するためのPOSTメソッドを用意し、storeの部分に記述します。

$item = Rest::create($request->all());
return response()->json([
    'data' => $item
], 201);

createでモデルを作成し、リクエストからきたデータを格納しています。
ステータスコードは作成成功を表す201を使用します。

show

次にidを用いてデータを取得するためのGETメソッドを用意します。
showの部分に記述していきます。

$item = Rest::find($rest); if ($item) { return response()->json([ 'data' => $item ], 200); } else { return response()->json([ 'message' => 'Not found', ], 404); }

今回はデータを取得できたかどうかで条件分岐を行っています。
取得できた場合は200取得できなかった場合は404のステータスコードを使用します。

update

次にidを用いてデータを更新するためのPUTメソッドを用意します。
updateの部分に記述していきます

$update = [ 'message' => $request->message, 'url' => $request->url ]; $item = Rest::where('id', $rest->id)->update($update); if ($item) { return response()->json([ 'message' => 'Updated successfully', ], 200); } else { return response()->json([ 'message' => 'Not found', ], 404); }

destroy

次にidを用いてデータを削除するためのDELETEメソッドを用意します。
destroyの部分に記述していきます。

$item = Rest::where('id', $rest->id)->delete();
if ($item) {
    return response()->json([
        'message' => 'Deleted successfully',
    ], 200);
} else {
    return response()->json([
        'message' => 'Not found',
    ], 404);
}

以上がそれぞれのアクションの機能になります。

続く。

あああ

-Laravel