7
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?

LaravelでToDoアプリのAPIを実装してみよう①

Last updated at Posted at 2024-01-23

前書き

初学者向けにLaravelでAPIを作る方法を記事にさせていただきます。
今回はシンプルなToDoアプリのAPIを実装していきます。
記事ではLaravel10系を使用しています。

Laravelの環境構築

今回は手軽に環境構築を行いたいのでSailを使用しようと思います。
Docker Desktopは事前にインストールしておいてください。
以下のコマンドを実行してアプリケーションの作成を行ってください。

curl -s "https://laravel.build/laravel-todo-api-sample" | bash

上手くいかない方は以下のQiitaの記事や公式ドキュメントをを参考にしみてください。

公式ドキュメント

phpMyAdminを追加

DBをGUIで見たい人はphpMyAdminをymlファイルに追記してDockerを再起動してください。
※必要がない人は飛ばしてください。

docker-compose.yml
    selenium:
        image: selenium/standalone-chrome
        extra_hosts:
            - "host.docker.internal:host-gateway"
        volumes:
            - "/dev/shm:/dev/shm"
        networks:
            - sail
    # ----- ここから追記 -----
    phpmyadmin:
        image: phpmyadmin/phpmyadmin
        ports:
            - 8080:80
        environment:
            MYSQL_USERNAME: '${DB_USERNAME}'
            MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
            PMA_HOST: mysql
        networks:
            - sail
    # ----- ここまで追記 -----
networks:
    sail:
        driver: bridge
volumes:
    sail-mysql:
        driver: local
    sail-redis:
        driver: local
    sail-meilisearch:
        driver: local

以下にのURLでphpMyAdminが表示されることを確認してください。
http://localhost:8080/

ログイン情報は.envを参考にしてください。
sailのデフォルトの設定では以下がログイン情報になっています。

ユーザ名 パスワード
sail password

テーブルの実装

今回はTODO用のテーブルを一つだけ用意して実装を行いたいと思います。

テーブル設計

todosテーブル

論理名 物理名 データ型 制約
ID id UNSIGNED BIGINT PRIMARY KEY,
AUTOINCREMENT
タイトル title VARCHAR(255) NOT NULL
詳細 description TEXT
完了状態 finished BOOLEAN NOT NULL
作成日時 created_at TIMESTAMP NOT NULL
更新日時 updated_at TIMESTAMP NOT NULL

マイグレーション

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

以下のコマンドを実行してマイグレーションファイルを作成してください。

./vendor/bin/sail artisan make:migration create_todos_table

テーブル定義

create_todos_table.phpを編集してToDoテーブルを定義してください。

create_todos_table.php
public function up()
{
    Schema::create('todos', function (Blueprint $table) {
            $table->id();
            $table->string('title')->comment('タイトル');
            $table->text('description')->nullable()->comment('完了状態');
            $table->boolean('finished')->default(false)->comment('詳細');
            $table->timestamp('created_at')->useCurrent()->comment('作成日時');
            $table->timestamp('updated_at')->nullable()->comment('更新日時');
            $table->comment('ToDo');
    });
}

マイグレーションの実行

以下のコマンドを実行してマイグレーションを実行してください。

./vendor/bin/sail artisan migrate

モデルの実装

モデルの作成

以下のコマンドを実行してマイグレーションを実行してください。

./vendor/bin/sail artisan make:model Todo

モデルの作成

Todo.phpを編集して、ToDoアイテムに関するロジックを追加してください。

Todo.php
class Todo extends Model
{
    protected $fillable = ['title', 'description', 'finished'];
}

テストデータの作成

Seederの作成

以下のコマンドを実行してSeederファイルを作成してください。

./vendor/bin/sail artisan make:seeder TodosTableSeeder

Seederファイルの編集

TodosTableSeeder.phpを編集してテストデータを作成するロジックを追加してください。
今回は10件のテストデータを作成します。

TodosTableSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class TodosTableSeeder extends Seeder
{
    public function run()
    {
        for ($i = 1; $i <= 10; $i++) {
            DB::table('todos')->insert([
                'title' => 'ToDo' . $i,
                'description' => 'これはToDo' . $i . 'の詳細です。',
                'finished' => (bool)random_int(0, 1),
                'created_at' => now(),
                'updated_at' => now(),
            ]);
        }
    }
}

Seederの実行

以下のコマンドを実行してSeederファイル実行し、テストデータの作成をしてください。

./vendor/bin/sail artisan db:seed --class=TodosTableSeeder

phpMyAdminなどを使用してテストデータが作られていることを確認してください。
http://localhost:8080/index.php?route=/sql&db=laravel_todo_api_sample&table=todos&pos=0

コントローラーの作成

以下のコマンドを実行してコントローラーを作成をしてください。

./vendor/bin/sail artisan make:controller TodoController

ToDoの一覧機能の実装

CRUDのR(Read)に該当する機能です。

コントローラーの編集

一覧データを取得するメソッドをTodoControllerに書いていきましょう。

TodoController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse; // 追加
use App\Models\Todo; // 追加
use Symfony\Component\HttpFoundation\Response; // 追加

class TodoController extends Controller
{
// --- 追加 ここから ---
    /**
     * ToDo一覧
     * 
     * @return JsonResponse
     */
    public function index(): JsonResponse
    {
        $todos = Todo::get();
        return response()->json(
            [
                'code' => Response::HTTP_OK,
                'todos' => $todos
            ]
        );
    }
// --- 追加 ここまで ---
}

Todo::get()でToDoテーブルのデータを全て取得し、response()->json($todos)とすることで取得したデータをJson形式にしてレスポンスすることができます。

:JsonResponseの記述は必須ではないですが、型宣言をすることによりindexメソッドがJsonResponseクラスのインスタンスを返すことを示してくれるようになります。
型宣言は、コードの可読性と安全性を向上させてくれるので覚えておくと良いと思います。

ルーティングの設定

api.phpを開いて編集してください。

routes/api.php
<?php

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

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "api" middleware group. Make something great!
|
*/

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

今回のアプリでは認証を行わないのでデフォルトで書かれているauth:sanctumは削除してしまいます。

routes/api.php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TodoController;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "api" middleware group. Make something great!
|
*/

Route::get('/todo', [TodoController::class, 'index']);

今回はデータの取得を行う処理なのでGETを使用します。

動作確認

Postman等を使用して動作確認を行ないます。

使い方がわからない方は以下の記事などを参考にしてください。

http://localhost/api/todo
上記URLにGETのHTTPリクエストを行いデータが取得できるか確認を行なってください。
スクリーンショット 2024-01-20 21.26.10.png

おまけ

一覧画面に完了状態の絞り込み機能を実装してみよう。

TodoController.php
    /**
     * ToDo一覧
     * 
     * @param Request $request
     * @return JsonResponse
     */
    public function index(Request $request): JsonResponse
    {
        $finished = $request->input('finished'); // クエリパラメータ 'finished' の値を取得

        $query = Todo::query();

        if ($finished === 'true') {
            $query->where('finished', true);
        } elseif ($finished === 'false') {
            $query->where('finished', false);
        }
        $todos = $query->get();

        return response()->json(
            [
                'code' => Response::HTTP_OK,
                'todos' => $todos
            ]
        );
    }

ToDoの新規登録機能の実装

CRUDのC(Create)に該当する機能です。

フォームリクエストの作成

以下のコマンドを実行してフォームリクエストを作成をしてください。

./vendor/bin/sail artisan make:request TodoCreateRequest

以下のようにフォームリクエストを編集してください。

TodoCreateRequest
<?php

namespace App\Http\Requests;

use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
use Symfony\Component\HttpFoundation\Response;

class TodoCreateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'title' => 'required|string|max:255',
            'description' => 'nullable|string',
            'finished' => 'boolean',
        ];
    }

    /**
     * バリデーションが失敗した場合の処理
     *
     * @param Validator $validator
     * @return void
     *
     * @throws HttpResponseException
     */
    protected function failedValidation(Validator $validator): void
    {
        throw new HttpResponseException(response()->json([
            'code' => Response::HTTP_BAD_REQUEST,
            'error' => $validator->errors()
        ], Response::HTTP_BAD_REQUEST));
    }
}

authorizeメソッドの返り値をtrueに変更することに注意してください。
failedValidationメソッドはFormRequestを使ってバリデーションを行いたいけど、そのままだとJSON形式でレスポンスを返してくれないのでエラー発生後にJSONで返してくれるように実装しています。

コントローラーの編集

データを新規登録するメソッドをTodoControllerに書いていきましょう。

TodoController

// Classの上に追加
use App\Http\Requests\TodoCreateRequest;
use Illuminate\Support\Facades\Log;
use Throwable;

    /**
     * ToDoを作成
     * 
     * @param TodoCreateRequest $request
     * @return JsonResponse
     */
    public function create(TodoCreateRequest $request): JsonResponse
    {
        try {
            $todo = Todo::create($request->all());

            return response()->json(
                [
                    'code' => Response::HTTP_OK,
                    'todo' => $todo
                ],
                Response::HTTP_OK
            );
        } catch (Throwable $e) {
            Log::error($e);

            return response()->json(
                [
                    'code' => Response::HTTP_INTERNAL_SERVER_ERROR,
                    'message' => 'Internal Server Error'
                ],
                Response::HTTP_INTERNAL_SERVER_ERROR
            );
        }
    }

成功事にはEloquentでcreate処理を書いてJSON形式でレスポンスをするだけですね。
処理が失敗した場合の処理も忘れないようにしておきましょう。

ルーティングの設定

api.phpにクリエイト処理のルーティングを設定をしてください。

api.php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\TodoController;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "api" middleware group. Make something great!
|
*/

Route::prefix('todo')->group(function () {
    Route::get('/', [TodoController::class, 'index']);
    Route::post('/create', [TodoController::class, 'create']);
});

同じtodoの処理を使用するので、ルーティングをグループ化してしまいましょう。
今回はPOSTです。

動作確認

http://localhost/api/todo/create
上記URLにPOSTのHTTPリクエストを行いデータが作成できるか確認を行なってください。

スクリーンショット 2024-01-20 23.06.12.png

後半へ続く

続きの記事はこちらになります。
https://qiita.com/kent0129/items/14169ef55d8e0e6425fb

7
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
7
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?