プログラミング

【GymCal】Laravel × Reactの連携方法

この記事は約10分で読めます。

フロントエンドにReact、バックエンドにLaravelを使ったアプリを作成するためにDBなしの簡易的な通信アプリを作成します。

作成手順をまとめますのでぜひ参考にしてみてください。

LaravelのAPI開発

Laravelの環境構築

以下をインストール済みです。

  • PHP 8.3.10
  • Composer 2.7.7
  • Laravel 11.20.0
Zsh
$ php -v
PHP 8.3.10 (cli) (built: Jul 30 2024 13:44:37) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.10, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.10, Copyright (c), by Zend Technologies
$ composer -V
Composer version 2.7.7 2024-06-10 22:11:12
PHP version 8.3.10 (/opt/homebrew/Cellar/php/8.3.10/bin/php)
Run the "diagnose" command to get more detailed diagnostics output.
$ php artisan --version
Laravel Framework 11.20.0

今回のプロジェクト構成は以下のとおりとします。

└── gymcal
    ├── backend
    └── frontend

gymcalディレクトリ直下にbackendディレクトリを作成します。

Zsh
$ composer create-project laravel/laravel backend

Laravelプロジェクトが作成されるため移動して実行してみます。

Zsh
$ cd backend
$ php artisan serve

Controllerの作成

簡易的なJSONをGETで返すAPIを1つ作成します。

backendディレクトリで以下のコマンドを実行します。

Zsh
$ php artisan make:controller ElementController

ElementController という名前の新しいコントローラーを作成します。このコントローラーは、app/Http/Controllers ディレクトリに生成されます。

次に作成されたElementController.phpを修正します。

app/Http/Controllers/ElementController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ElementController extends Controller
{
  public function index()
  {
    return response()->json(
      [
        "elements" => [
          [
            "id" => 1,
            "event" => 1,
            "element_group" => 3,
            "name" => "後方抱え込み2回宙返り3回ひねり",
            "alias" => "リジョンソン",
            "difficulty" => 7,
            "row_number" => 1
          ],
          [
            "id" => 2,
            "event" => 1,
            "element_group" => 4,
            "name" => "前方伸身宙返り3回ひねり",
            "alias" => "シライ2",
            "difficulty" => 6,
            "row_number" => 2
          ]
        ]
      ],
      200,
      [],
      JSON_UNESCAPED_UNICODE //文字化け対策
    );
  }
}

api.phpの作成

APIルーティングの設定を記述するapi.phproutesディレクトリに作成します。

routes/api.php
<?php

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

Route::get('elements',[ElementController::class, 'index']);

api.phpにルーティングを設定した場合はhttp://localhost:8000/api/〇〇 とルーティングされます。

ブラウザでhttp://localhost:8000/api/elementsにアクセスしてみます。

 1. 初期設定と問題発生

routes/api.phpでAPIのルーティングを設定した際、http://localhost:8000/api/elements へのリクエストが「404 Not Found」として返ってくる問題に直面しました。

2. 基本的なチェック

まず、ルーティングが適切に設定されているか確認するために、php artisan route:list を確認しましたが、routes/api.phpのルートはリストに反映されませんでした。

3. 最終的な解決策

bootstrap/app.phpファイルにて、APIルーティングを適切に読み込むための設定が不足していることに気付きました。具体的には、withRoutingメソッドにapi.phpのルートを追加する必要がありました。

bootstrap/app.php
<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__ . '/../routes/web.php',
        api: __DIR__ . '/../routes/api.php', // ここを追加
        commands: __DIR__ . '/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        //
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

bootstrap/app.phpファイルに気づいたのは「web.php」で検索した結果です。
routes/web.phpに書いたルーティングはphp artisan route:listで確認できたため、ファイル間検索で言及しているところがないかと思い付くに至りました。

ReactのAPI呼び出し

Reactの環境構築

以下をインストール済みです。

  • node.js 18.17.0
  • React 18.3.1
  • TypeScript 5.5.2
Zsh
$ node -v       
v18.17.0
$ npm list react
frontend@0.1.0 /Users/junyamagami/Developments/gymcal/frontend
├─┬ @testing-library/react@13.4.0
 └── react@18.3.1 deduped
├─┬ react-dom@18.3.1
 └── react@18.3.1 deduped
├─┬ react-scripts@5.0.1
 └── react@18.3.1 deduped
└── react@18.3.1
$ tsc -v
Version 5.5.2

TypeScriptでReactプロジェクトを作成します。

Zsh
npx create-react-app frontend --template typescript

起動できることを確認します。

Zsh
npm start

APIリクエスト作成

Laravelが提供するAPIにリクエストを送り、データを取得する記述を作成します。

src/App.tsx
import React, { useEffect } from 'react';
import './App.css';

const App: React.FC = () => {
  const [elements, setElements] = React.useState([]);
  const url = "http://localhost:8000/api/elements"


  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch(url);
        const data = await response.json();
        console.log(data.elements);
        setElements(data.elements);
      } catch (error) {
        console.log(error);
      }
    };
    fetchData();
  }, []);

  return (
    <div className="App">
      {elements.map((element: any) => (
        <div key={element.id}>
          <p>id: {element.id}</p>
          <p>event: {element.event}</p>
          <p>element_group: {element.element_group}</p>
          <p>name: {element.name}</p>
          <p>alias: {element.alias}</p>
          <p>difficulty: {element.difficulty}</p>
          <p>row_number: {element.row_number}</p>
        </div>
      ))}
    </div>
  );
}

export default App;

データが取得できることが確認できます。

まとめ

以上がReactとLaravelの連携方法でした。

LaravelでAPIを提供したのは初めてだったので良い勉強になりました。

参考文献

LaravelでAPIを作成しReactと連携する流れ

コメント