1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

LaravelでのCRUD操作が行えるREST APIの作成

Last updated at Posted at 2022-09-25

Laravelを使用して、CRUD(作成、読み込み、更新、削除)ができるREST APIを作成します。
内容について、詳しく説明を行っていませんが、とりあえず手を動かしてLaravelでREST APIを作ってみたいといった際に、参考になれば幸いです。

環境について

Laravel環境は、以下のDocker開発環境を使用させていただきます。
Docker環境の構築については、リンク先にてご確認ください。
最強のLaravel開発環境をDockerを使って構築する

接続テスト

実際にAPIが作動しているか確認するために、接続テスト用のエンドポイントを作成します。
ブラウザで、「127.0.0.1/api/test」を開いた際に、「接続テスト成功!」が表示されると、接続テスト成功です。

src/routes/api.php
<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

// 接続できているか確認用
Route::get('/test', function () { return '接続テスト成功!'; });

スクリーンショット 2022-09-25 7.57.03.png

マイグレーションファイルの作成

データベースのテーブル定義を作成します。
「birdテーブル」と「typeテーブル」を作成します。

  • birdテーブル
カラム名 文字数制限 NULL許容 備考
id bigint - - 自動生成されるID
created_at timestanp - レコードがインサートされた時間
updated_at timestanp - レコードが更新された時間
deleted_at timestanp - レコードが削除された時間(論理削除)
name varchar 100文字 - 鳥の名前
type bigint - - typeテーブルとのリレーション
  • typeテーブル
カラム名 文字数制限 NULL許容 備考
id bigint - - 自動生成されるID
created_at timestanp - レコードがインサートされた時間
updated_at timestanp - レコードが更新された時間
deleted_at timestanp - レコードが削除された時間(論理削除)
name varchar 100文字 - 鳥類

※ 環境についてで紹介したDocker環境の場合、コンテナ内のターミナルを操作する必要があります。

Dockerコンテナにターミナルをアタッチする

docker exec -it docker-laravel-app-1 sh

コンテナにアタッチしたことを確かめるため、Laravelのバージョンを確認する。

php artisan -v

Laravelのバージョンが表示されると、コンテナにアタッチできています。

スクリーンショット 2022-09-25 11.57.09.png

この後のコマンド操作はアタッチしたシェルで作業します。

bardテーブルの作成

php artisan make:migration create_bird_table

「src/database/migrations/」フォルダ内の「YYYY_MM_DD_hhmmss_create_bird_table.php」を編集します。
※ コマンドの実施時間によってファイル名が異なります。

src/database/migrations/2022_09_01_000001_create_bird_table.php
    // 省略
    public function up()
    {
        Schema::create('bird', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
            // --- 追加 ---
            // ソフトデリート
            $table->softDeletes()->comment('ソフトデリート');
            // 名前(100文字)
            $table->string('name', 100)->comment('名前');
            // 種別(typeテーブルとのリレーション)
            $table->bigInteger('type')->comment('種別');
            // -----------
        });
    }
    // 省略

typeテーブルの作成

php artisan make:migration create_type_table

「src/database/migrations/」フォルダ内の「YYYY_MM_DD_hhmmss_create_type_table.php」を編集します。
※ コマンドの実施時間によってファイル名が異なります。

src/database/migrations/2022_09_01_000002_create_type_table.php
    // 省略
    public function up()
    {
        Schema::create('type', function (Blueprint $table) {
            $table->id();
            $table->timestamps();
            // --- 追加 ---
            // ソフトデリート
            $table->softDeletes()->comment('ソフトデリート');
            // 名前(100文字)
            $table->string('name', 100)->comment('名前');
            // -----------
        });
    }
    // 省略

シーダーファイルの作成

「birdテーブル」と「typeテーブル」のデータベースにインサートするデータを記述します。

birdテーブルのシーダー作成

php artisan make:seeder BirdTableSeeder

「src/database/seeders/」フォルダ内の「BirdTableSeeder.php」を編集します。

src/database/seeders/BirdTableSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
// --- 追加 ---
use Illuminate\Support\Facades\DB;

class BirdTableSeeder extends Seeder
{
    public function run()
    {
        // --- 追加 ---
        // 日本時間に設定
        date_default_timezone_set('Asia/Tokyo');
        DB::table('bird')->insert([
            [
                'created_at' => date("Y/m/d H:i:s"),
                'updated_at' => date("Y/m/d H:i:s"),
                'name' => 'にわとり',
                'type' => 1,
            ], [
                'created_at' => date("Y/m/d H:i:s"),
                'updated_at' => date("Y/m/d H:i:s"),
                'name' => 'イワトビペンギン',
                'type' => 2,
            ], [
                'created_at' => date("Y/m/d H:i:s"),
                'updated_at' => date("Y/m/d H:i:s"),
                'name' => 'スズメ',
                'type' => 3,
            ]
        ]);
        // -----------
    }
}

typeテーブルのシーダー作成

php artisan make:seeder TypeTableSeeder

「src/database/seeders/」フォルダ内の「TypeTableSeeder.php」を編集します。

src/database/seeders/TypeTableSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
// --- 追加 ---
use Illuminate\Support\Facades\DB;

class TypeTableSeeder extends Seeder
{
    public function run()
    {
        // --- 追加 ---
        // 日本時間に設定
        date_default_timezone_set('Asia/Tokyo');
        DB::table('type')->insert([
            [
                'created_at' => date("Y/m/d H:i:s"),
                'updated_at' => date("Y/m/d H:i:s"),
                'name' => 'キジ科',
            ], [
                'created_at' => date("Y/m/d H:i:s"),
                'updated_at' => date("Y/m/d H:i:s"),
                'name' => 'ペンギン科',
            ], [
                'created_at' => date("Y/m/d H:i:s"),
                'updated_at' => date("Y/m/d H:i:s"),
                'name' => 'スズメ科',
            ]
        ]);
        // -----------
    }
}

シーダーファイルの読み込み設定

「src/database/seeders/」フォルダ内の「DatabaseSeeder.php」を編集します。

src/database/seeders/DatabaseSeeder.php
<?php

namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        // --- 追加 ---
        $this->call([
            // 鳥テーブル
            BirdTableSeeder::class,
            // 分類テーブル
            TypeTableSeeder::class,
         ]);
         // -----------
    }
}

マイグレーションとシーディングの実行

php artisan migrate --seed

データベースのマイグレーションとシーディングが正常に行われると、bardテーブルとtypeテーブルにデータが挿入されます。

スクリーンショット 2022-09-25 17.34.18.png

モデルの作成

birdテーブルのモデルとtypeテーブルのモデルを作成します。

birdモデル

php artisan make:model Bird

「src/app/Models/」フォルダ内の「Bird.php」を編集します。

src/app/Models/Bird.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
// --- 追加 ---
use Illuminate\Database\Eloquent\SoftDeletes;

class Bird extends Model
{
    use HasFactory;

    // --- 追加 ---
    use SoftDeletes;
    protected $table = 'bird';
    protected $guarded = array('id');
    // -----------
}

typeモデル

php artisan make:model Type

「src/app/Models/」フォルダ内の「Type.php」を編集します。

src/app/Models/Type.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
// --- 追加 ---
use Illuminate\Database\Eloquent\SoftDeletes;

class Type extends Model
{
    use HasFactory;

    // --- 追加 ---
    use SoftDeletes;
    protected $table = 'type';
    protected $guarded = array('id');
    // -----------
}

鳥の名前を取得するコントローラーの作成

php artisan make:controller BirdController --api

「src/app/Http/Controllers/」フォルダ内の「BirdController.php」を編集します。

src/app/Http/Controllers/BirdController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

// --- 追加 ---
use App\Models\Bird;
use App\Models\Type;
use Illuminate\Support\Facades\DB;

class BirdController extends Controller
{
    public function index()
    {
        // --- 追加 ---
        $result = Bird::select(
            // birdテーブルのid
            'bird.id as id',
            // birdテーブルの鳥の名前
            'bird.name as name',
            // typeテーブルの鳥の分類名
            'type.name as type'
        )->join('type', function ($type) {
            // bird.typeとtype.idとの紐付け
            $type->on('bird.type', '=', 'type.id');
        })->get();
        return $result;
        // -----------
    }
    // 省略

鳥の名前と種類を返すAPIを作成しました。

鳥の名前を取得するエンドポイントの定義

「src/routes/」フォルダ内の「api.php」を編集します。

src/routes/api.php
// 省略
Route::prefix('bird')->group(function () {
    // 鳥の名前と種類の表示
    Route::get('/', 'App\Http\Controllers\BirdController@index');
});
// 省略

鳥の名前を取得するAPIのテスト

REST APIクライアントツール(postmanや、VS Code拡張のThunder Clientなど。例では、Thunder Clientを使用しています。)で、「127.0.0.1/api/bird」にGETリクエストを送ると、birdテーブルのid、鳥の名前、typeテーブルの分類名がJSON形式で表示されます。

※ APIにリクエストを送信した際に、サーバーエラーが発生する場合は、Laravelのキャッシュクリアを試してみてください。
参考:Laravel 粘着質なcacheを削除しよう!

スクリーンショット 2022-09-25 19.52.14.png

鳥の名前と種類名を登録するコントローラーの作成

「src/app/Http/Controllers/」フォルダ内の「BirdController.php」を編集します。

バリデーションとして、鳥の種類名と名前が存在しない場合は、登録せずに、エラーレスポンスを返すようにしています。

src/app/Http/Controllers/BirdController.php
    // 省略
    public function store(Request $request)
    {
        // --- 追加 ---
        // 登録したい内容を受け取る
        $form = $request->all();

        // バリデーション
        // 鳥の種類名が存在するか
        if (!isset($form['type'])) {
            return response()->json(["鳥の種類名が存在しません"], 400);
        }
        // 鳥の名前が存在するか
        if (!isset($form['name'])) {
            return response()->json(["鳥の名前が存在しません"], 400);
        }

        // トランザクション
        DB::beginTransaction();
        // 日本時間に設定
        date_default_timezone_set('Asia/Tokyo');

        try {
            // 先に種類を登録
            $type = new Type();
            $type->fill([
                // 登録日時
                'created_at' => date("Y/m/d H:i:s"),
                // 更新日時
                'updated_at' => date("Y/m/d H:i:s"),
                // 種類名
                'name' => $form['type'],
            ])->save();

            // 鳥の種類を登録
            $bird = new Bird();
            $bird->fill([
                // 登録日時
                'created_at' => date("Y/m/d H:i:s"),
                // 更新日時
                'updated_at' => date("Y/m/d H:i:s"),
                // 鳥の名前
                'name' => $form['name'],
                // 鳥の種類
                'type' => $type->id,
            ])->save();

            // コミット
            DB::commit();
            return $bird;
        } catch (Exception $exception) {
            // 例外処理
            // ロールバック
            DB::rollBack();
            throw $exception;
        }
        // -----------
    }
    // 省略

鳥の名前と種類名を登録するエンドポイントの定義

「src/routes/」フォルダ内の「api.php」を編集します。

src/routes/api.php
// 省略
Route::prefix('bird')->group(function () {
    // 鳥の名前と種類の表示
    Route::get('/', 'App\Http\Controllers\BirdController@index');
    // 鳥の名前と種類を登録
    Route::post('/', 'App\Http\Controllers\BirdController@store');
});
// 省略

鳥の名前と種類名を登録するAPIのテスト

REST APIクライアントツールで「127.0.0.1/api/bird」にPOSTリクエストを送ると、鳥の名前と種類が登録できます。

  • リクエストボディ(JSON)
{
  "type": "オウム科",
  "name": "オカメインコ"
}

スクリーンショット 2022-09-25 20.22.21.png

DBを見ると、POSTリクエストのボディの内容が登録されていることが確認できます。

スクリーンショット 2022-09-25 20.24.13.png

鳥の名前と種類名を編集するコントローラーの作成

「src/app/Http/Controllers/」フォルダ内の「BirdController.php」を編集します。

バリデーションとして、birdテーブルに編集対象が存在するか、鳥の種類名と名前が存在しない場合は、登録せずに、エラーレスポンスを返すようにしています。

src/app/Http/Controllers/BirdController.php
    // 省略
    public function update(Request $request, $id)
    {
        // --- 追加 ---
        // 登録したい内容を受け取る
        $form = $request->all();

        // バリデーション
        // 編集したいデータが存在するか
        if (!Bird::where('id', $id)->exists()) {
            return response()->json(["編集対象のレコードが存在しません"], 400);
        }
        // 鳥の種類名が存在するか
        if (!isset($form['type'])) {
            return response()->json(["鳥の種類名が存在しません"], 400);
        }
        // 鳥の名前が存在するか
        if (!isset($form['name'])) {
            return response()->json(["鳥の名前が存在しません"], 400);
        }

        // トランザクション
        DB::beginTransaction();
        // 日本時間に設定
        date_default_timezone_set('Asia/Tokyo');

        try {
            // birdテーブルのid検索
            $bird = Bird::find($id);
            // アップデート処理を行う
            $bird->fill([
                // 更新日時
                'updated_at' => date("Y/m/d H:i:s"),
                // 鳥の名前
                'name' => $form['name'],
            ])->update();

            // typeデーブルのid検索
            $type = Type::find($bird->type);
            // アップデート処理を行う
            $type->fill([
                // 更新日時
                'updated_at' => date("Y/m/d H:i:s"),
                // 鳥の種類
                'name' => $form['type'],
            ])->update();

            // コミット
            DB::commit();

            return response()->json([
                "bird" => $bird,
                "type" => $type
            ], 200);
        } catch (Exception $exception) {
            // 例外処理
            // ロールバック
            DB::rollBack();
            throw $exception;
        }
        // -----------
    }
    // 省略

鳥の名前と種類名を編集するエンドポイントの定義

「src/routes/」フォルダ内の「api.php」を編集します。

src/routes/api.php
// 省略
Route::prefix('bird')->group(function () {
    // 鳥の名前と種類の表示
    Route::get('/', 'App\Http\Controllers\BirdController@index');
    // 鳥の名前と種類を登録
    Route::post('/', 'App\Http\Controllers\BirdController@store');
    // 鳥の名前と種類を更新
    Route::put('/update/{id}', 'App\Http\Controllers\BirdController@update');
});
// 省略

鳥の名前と種類名を編集するAPIのテスト

REST APIクライアントツールで「127.0.0.1/api/bird/update/2」にPUTリクエストを送ると、birdテーブルのidが2番(ペンギン科、イワトビペンギン)の鳥の名前と種類が編集できます。

  • リクエストボディ(JSON)
{
  "type": "ペンギン目ペンギン科",
  "name": "キングペンギン"
}

スクリーンショット 2022-09-25 20.49.51.png

DBを見ると、PUTリクエストのボディの内容に更新されていることが確認できます。

スクリーンショット 2022-09-25 20.50.46.png

鳥の名前と種類名を論理削除するコントローラーの作成

「src/app/Http/Controllers/」フォルダ内の「BirdController.php」を編集します。

src/app/Http/Controllers/BirdController.php
    // 省略
    public function destroy($id)
    {
        // --- 追加 ---
        // バリデーション
        // 削除対象のレコードが存在するか
        if (!Bird::where('id', $id)->exists()) {
            return response()->json(["削除対象のレコードが存在しません"], 400);
        }

        // トランザクション
        DB::beginTransaction();
        // 日本時間に設定
        date_default_timezone_set('Asia/Tokyo');

        try {
            // 削除対象のbirdレコードに紐づくtypeレコードのidを求める
            $TypeId = Bird::select('type')->where('id', $id)->first();
            // 削除したいbirdレコードを探し、削除
            Bird::find($id)->delete();
            // birdレコードに紐づくtypeレコードも削除
            Type::find($TypeId->type)->delete();
            // コミット
            DB::commit();
            return response()->json(['削除完了'], 200);
        } catch (Exception $exception) {
            // 例外処理
            // ロールバック
            DB::rollBack();
            throw $exception;
        }
        // -----------
    }
    // 省略

鳥の名前と種類名を論理削除するエンドポイントの定義

「src/routes/」フォルダ内の「api.php」を編集します。

src/routes/api.php
// 省略
Route::prefix('bird')->group(function () {
    // 鳥の名前と種類の表示
    Route::get('/', 'App\Http\Controllers\BirdController@index');
    // 鳥の名前と種類を登録
    Route::post('/', 'App\Http\Controllers\BirdController@store');
    // 鳥の名前と種類を更新
    Route::put('/update/{id}', 'App\Http\Controllers\BirdController@update');
    // 鳥の名前と種類を論理削除
    Route::delete('/destroy/{id}', 'App\Http\Controllers\BirdController@destroy');
});
// 省略

鳥の名前と種類名を編集するAPIのテスト

REST APIクライアントツールで「127.0.0.1/api/bird/destroy/4」にDELETEリクエストを送ると、birdテーブルのidが4番(オウム科、オカメインコ)のレコードが論理削除されます。

スクリーンショット 2022-09-25 21.13.58.png

DBを見ると、birdテーブルの「オカメインコ」とtypeテーブルの「オウム科」のレコードのdeleted_atに日付が入っていることが確認できます。

スクリーンショット 2022-09-25 21.24.11.png


以上で、Laraveで一通りのCRUD操作を行うREST APIができます。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?