Laravel Sailを使ってスポット情報を表示するAPIを作成する方法

Laravel Sailを使ってプロジェクトをセットアップし、スポット情報をデータベースに保存して、リスト形式および単一のスポット情報をAPIで表示する手順を紹介します。

手順概要

  1. Laravelプロジェクトの作成(Laravel Sailを使用)
  2. データベースの設定
  3. スポット情報を保存するテーブルとモデルの作成
  4. routes/api.php の追加とAPIプレフィックスの設定
  5. CSVファイルからデータをインポートするSeederの作成
  6. スポット情報のリスト表示APIの作成
  7. 単一スポット情報をAPIで表示
  8. リストおよび単体表示のJSONサンプル
  9. 利用しているバージョン情報

1. Laravelプロジェクトの作成

まず、Laravel Sailを使ってプロジェクトを作成します。次のコマンドを実行し、higashimurayama_db というプロジェクトを作成します。

curl -s "https://laravel.build/higashimurayama_db" | bash

このコマンドは、プロジェクトフォルダを作成し、必要なファイルをダウンロードします。次に、そのディレクトリに移動し、Sailを使ってDockerコンテナを起動します。

cd higashimurayama_db
./vendor/bin/sail up -d

これで、Laravelの環境がDocker上で立ち上がり、http://localhost にアクセスするとLaravelのウェルカムページが表示されます。


2. データベースの設定

Laravel SailはMySQLコンテナも起動するため、.env ファイルにMySQLの接続設定を記述します。

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=higashimurayama_db
DB_USERNAME=sail
DB_PASSWORD=password

次に、データベースに必要なテーブルを作成します。まず、スポット情報を保存するためのマイグレーションを作成します。

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

作成されたマイグレーションファイルを以下のように編集します。

Schema::create('spots', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('postal_code')->nullable();
    $table->string('prefecture');
    $table->string('address');
    $table->string('phone_number')->nullable();
    $table->string('fax')->nullable();
    $table->string('url')->nullable();
    $table->string('category');
    $table->decimal('latitude', 10, 8)->nullable();
    $table->decimal('longitude', 11, 8)->nullable();
    $table->string('map_url')->nullable();
    $table->timestamps();
});

これを実行してテーブルを作成します。

./vendor/bin/sail artisan migrate

3. スポット情報を保存するモデルの作成

次に、スポット情報を管理するモデルを作成します。

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

app/Models/Spot.php ファイルに次のコードを追加します。

<?php

namespace App\Models;

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

class Spot extends Model
{
    use HasFactory;

    protected $fillable = ['name', 'postal_code', 'prefecture', 'address', 'phone_number', 'fax', 'url', 'category', 'latitude', 'longitude', 'map_url'];
}

これで、スポット情報を保存するためのモデルが作成されました。


4. routes/api.php の追加とAPIプレフィックスの設定

Laravel 11では routes/api.php がデフォルトで含まれていないため、手動で作成し、AppServiceProvider にルーティング設定を追加する必要があります。

routes/api.php の追加

まず、routes/api.php を新規作成し、APIルートを定義します。

routes/api.php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\SpotController;

Route::get('/spots', [SpotController::class, 'index']); // スポットリストの表示
Route::get('/spots/{id}', [SpotController::class, 'show']); // 単一スポット情報の表示

AppServiceProvider.php にAPIプレフィックスの設定を追加

次に、AppServiceProvider.php にAPIルートを設定します。これにより、APIルートが /api/ プレフィックス付きで動作するようになります。

app/Providers/AppServiceProvider.php

use Illuminate\Support\Facades\Route;

public function boot(): void
{
    Route::middleware('api')
        ->prefix('api')
        ->group(base_path('routes/api.php'));
}

これで、APIプレフィックスが適用され、http://localhost/api/spots でスポット情報を取得できるようになります。

5. CSVファイルからデータをインポートするSeederの作成

LaravelのSeederを使って、あらかじめ用意したCSVファイルからスポットデータをデータベースにインポートできます。

CSVファイルの準備

まず、database/data/ ディレクトリにインポートするCSVファイルを配置します。例えば、spots.csv というファイルを用意し、次のようなデータを格納します。

name,postal_code,prefecture,address,phone_number,fax,url,category,latitude,longitude,map_url
スポット1,123-4567,東京都,東村山市1-2-3,090-1234-5678,03-1234-5678,http://example.com,公園,35.123456,139.123456,http://maps.google.com/?q=35.123456,139.123456
スポット2,234-5678,東京都,東村山市2-3-4,090-2345-6789,,http://example2.com,病院,35.234567,139.234567,http://maps.google.com/?q=35.234567,139.234567

Seederの作成

次に、Seederを作成します。

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

database/seeders/SpotSeeder.php を編集し、CSVファイルを読み込み、データベースに挿入する処理を追加します。

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\Spot;
use League\Csv\Reader;

class SpotSeeder extends Seeder
{
    public function run()
    {
        // CSVファイルを読み込む
        $csv = Reader::createFromPath(database_path('data/spots.csv'), 'r');
        $csv->setHeaderOffset(0); // 1行目をヘッダーとする

        $records = $csv->getRecords();

        foreach ($records as $record) {
            Spot::create([
                'name' => $record['name'],
                'postal_code' => $record['postal_code'],
                'prefecture' => $record['prefecture'],
                'address' => $record['address'],
                'phone_number' => $record['phone_number'],
                'fax' => $record['fax'],
                'url' => $record['url'],
                'category' => $record['category'],
                'latitude' => $record['latitude'],
                'longitude' => $record['longitude'],
                'map_url' => $record['map_url'],
            ]);
        }
    }
}

CSVのインポート実行

Seederを実行してCSVデータをデータベースにインポートします。

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

これで、CSVファイルからスポットデータがデータベースにインポートされます。

以下は「6. スポット情報のリスト表示APIの作成」以降の再生成された内容です。


6. スポット情報のリスト表示APIの作成

次に、すべてのスポット情報をリスト形式で取得できるAPIを作成します。

まず、SpotController を作成します。

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

次に、SpotController.php を以下のように編集します。

<?php

namespace App\Http\Controllers;

use App\Models\Spot;

class SpotController extends Controller
{
    // 全スポット情報のリストを取得
    public function index()
    {
        $spots = Spot::all();
        return response()->json($spots);
    }

    // 単一スポット情報を取得
    public function show($id)
    {
        $spot = Spot::find($id);

        if ($spot) {
            return response()->json($spot);
        } else {
            return response()->json(['message' => 'Spot not found'], 404);
        }
    }
}

次に、routes/api.php にリスト表示と単一表示のルートを追加します。

routes/api.php

use App\Http\Controllers\SpotController;

Route::get('/spots', [SpotController::class, 'index']); // スポットリストの表示
Route::get('/spots/{id}', [SpotController::class, 'show']); // 単一スポット情報の表示

これで、スポット情報をリスト形式で表示するAPIと、単一のスポット情報を取得するAPIが完成しました。

7. 単一スポット情報をAPIで表示

特定のスポットIDに基づいて、単一のスポット情報を取得するAPIも SpotController 内にすでに作成されています。これにより、特定のスポットにアクセスするためには、次のようなURLを使用します。

http://localhost/api/spots/{id}

たとえば、スポットIDが2のデータを取得するには次のURLにアクセスします。

http://localhost/api/spots/2

8. リストおよび単体表示のJSONサンプル

次に、リスト表示と単一表示のJSONレスポンスのサンプルを紹介します。

リスト表示のJSONサンプル

http://localhost/api/spots にアクセスすると、次のようなレスポンスが返ってきます(サンプルデータ)。

[
    {
        "id": 1,
        "name": "スポット1",
        "postal_code": "123-4567",
        "prefecture": "東京都",
        "address": "東村山市1-2-3",
        "phone_number": "090-1234-5678",
        "fax": "03-1234-5678",
        "url": "http://example.com",
        "category": "公園",
        "latitude": 35.123456,
        "longitude": 139.123456,
        "map_url": "http://maps.google.com/?q=35.123456,139.123456",
        "created_at": "2024-10-09T07:38:06.000000Z",
        "updated_at": "2024-10-09T07:38:06.000000Z"
    },
    {
        "id": 2,
        "name": "スポット2",
        "postal_code": "234-5678",
        "prefecture": "東京都",
        "address": "東村山市2-3-4",
        "phone_number": "090-2345-6789",
        "fax": null,
        "url": "http://example2.com",
        "category": "病院",
        "latitude": 35.234567,
        "longitude": 139.234567,
        "map_url": "http://maps.google.com/?q=35.234567,139.234567",
        "created_at": "2024-10-09T07:38:06.000000Z",
        "updated_at": "2024-10-09T07:38:06.000000Z"
    }
]

単一表示のJSONサンプル

http://localhost/api/spots/1 にアクセスすると、次のような単一のスポット情報が返ってきます。

{
    "id": 1,
    "name": "スポット1",
    "postal_code": "123-4567",
    "prefecture": "東京都",
    "address": "東村山市1-2-3",
    "phone_number": "090-1234-5678",
    "fax": "03-1234-5678",
    "url": "http://example.com",
    "category": "公園",
    "latitude": 35.123456,
    "longitude": 139.123456,
    "map_url": "http://maps.google.com/?q=35.123456,139.123456",
    "created_at": "2024-10-09T07:38:06.000000Z",
    "updated_at": "2024-10-09T07:38:06.000000Z"
}

9. 利用しているバージョン情報

この記事で使用しているツールやフレームワークのバージョン情報を以下に記載します。

  • Laravel: 11.27.2
  • PHP: 8.3.12
  • MySQL: 8.0.32
  • Composer: 2.8.1
  • League\Csv: 9.16.0

コメント

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