第4回 RESTful APIの設計と実装

Laravel WebAPI開発

こんにちは、PHP開発者の皆さん!この連載の第4回では、Laravel 10を使ってRESTful APIを設計し、実装する方法について詳しく解説します。RESTful APIは、Webサービスのデータ交換に広く使われており、シンプルで一貫性のある設計が特徴です。それでは、始めましょう!

1. RESTful APIとは

REST(Representational State Transfer)は、HTTPをベースにしたアーキテクチャスタイルです。RESTful APIは、リソースをエンドポイントとして提供し、HTTPメソッド(GET、POST、PUT、DELETEなど)を使用してリソースの操作を行います。

2. API用のルーティング設定

まずは、API用のルーティングを設定します。APIルートは、routes/api.php ファイルに定義します。

APIルートの定義

routes/api.php を開き、以下のコードを追加します。

routes/api.php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\PostController;

Route::middleware('api')->group(function () {
    Route::resource('posts', PostController::class);
});
PHP

これにより、/api/posts エンドポイントが作成され、リソースコントローラに対応するルートが自動的に生成されます。

3. コントローラの作成

次に、API用のコントローラを作成します。artisan コマンドを使用して生成しましょう。

./vendor/bin/sail artisan make:controller Api/PostController --api
Bash

このコマンドにより、app/Http/Controllers/Api/PostController.php ファイルが生成されます。

コントローラの編集

生成されたコントローラにメソッドを追加し、基本的なCRUD操作を実装します。

app/Http/Controllers/Api/PostController.php
namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        return response()->json(Post::all(), 200);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'body' => 'required|string',
        ]);

        $post = Post::create($validated);

        return response()->json($post, 201);
    }

    /**
     * Display the specified resource.
     */
    public function show($id)
    {
        $post = Post::find($id);

        if (is_null($post)) {
            return response()->json(['message' => 'Post not found'], 404);
        }

        return response()->json($post, 200);
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, $id)
    {
        $validated = $request->validate([
            'title' => 'sometimes|required|string|max:255',
            'body' => 'sometimes|required|string',
        ]);

        $post = Post::find($id);

        if (is_null($post)) {
            return response()->json(['message' => 'Post not found'], 404);
        }

        $post->update($validated);

        return response()->json($post, 200);
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy($id)
    {
        $post = Post::find($id);

        if (is_null($post)) {
            return response()->json(['message' => 'Post not found'], 404);
        }

        $post->delete();

        return response()->json(['message' => 'Post deleted successfully'], 204);
    }
}
PHP

このコントローラでは、index, store, show, update, destroy の各メソッドを実装しています。これにより、基本的なCRUD操作が可能になります。

4. バリデーションの追加

リクエストデータのバリデーションを追加して、不正なデータの保存を防ぎます。上記のコントローラコード内で、storeupdate メソッドにバリデーションルールを追加しています。

バリデーションの例

例えば、store メソッドでは以下のようにバリデーションを行います。

app/Http/Controllers/Api/PostController.php
$validated = $request->validate([
    'title' => 'required|string|max:255',
    'body' => 'required|string',
]);
PHP

バリデーションに失敗した場合、Laravelは自動的に400ステータスコードとエラーメッセージを返します。

5. APIテスト

最後に、APIエンドポイントが正しく動作することを確認するために、テストを行います。Laravelでは、HTTPテストを簡単に行うためのツールが用意されています。

テストの作成

artisan コマンドを使用してテストクラスを作成します。

./vendor/bin/sail artisan make:test PostApiTest
Bash

生成されたテストクラスにテストメソッドを追加します。

app/Tests/PostApiTest.php
namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
use App\Models\Post;

class PostApiTest extends TestCase
{
    use RefreshDatabase;

    /**
     * A basic feature test example.
     */
    public function test_can_create_post()
    {
        $data = [
            'title' => 'Test Title',
            'body' => 'Test Body',
        ];

        $response = $this->postJson('/api/posts', $data);

        $response
            ->assertStatus(201)
            ->assertJson([
                'title' => 'Test Title',
                'body' => 'Test Body',
            ]);
    }

    public function test_can_get_all_posts()
    {
        Post::factory()->count(3)->create();

        $response = $this->getJson('/api/posts');

        $response
            ->assertStatus(200)
            ->assertJsonCount(3);
    }

    public function test_can_get_single_post()
    {
        $post = Post::factory()->create();

        $response = $this->getJson("/api/posts/{$post->id}");

        $response
            ->assertStatus(200)
            ->assertJson([
                'title' => $post->title,
                'body' => $post->body,
            ]);
    }

    public function test_can_update_post()
    {
        $post = Post::factory()->create();

        $data = [
            'title' => 'Updated Title',
            'body' => 'Updated Body',
        ];

        $response = $this->putJson("/api/posts/{$post->id}", $data);

        $response
            ->assertStatus(200)
            ->assertJson([
                'title' => 'Updated Title',
                'body' => 'Updated Body',
            ]);
    }

    public function test_can_delete_post()
    {
        $post = Post::factory()->create();

        $response = $this->deleteJson("/api/posts/{$post->id}");

        $response->assertStatus(204);
    }
}
PHP

テストの実行

以下のコマンドを実行してテストを実行します。

./vendor/bin/sail artisan test
Bash

すべてのテストがパスすれば、APIが正しく動作していることが確認できます。

6. まとめ

この記事では、Laravel 10を使ってRESTful APIを設計し、実装する方法について解説しました。APIの設計と実装を通じて、データのやり取りを効率的に行う方法を学びました。次回は、APIの認証と認可について学びます。それでは、次の記事でお会いしましょう!

次の記事: 第5回 バリデーションとエラーハンドリング

コメント

タイトルとURLをコピーしました