Photoruction工事中!

Photoructionの開発ブログです!

Laravel + Brefで実現するサーバーレスアプリケーション

はじめに

BPOチームの春冨です。

今回は業務でサーバーレスアプリケーションを実装することになり、Brefというツールを使用する予定です。初めて使うツールなので、まずは簡単に試してみました。この記事ではその実践内容を紹介します。

Bref とは

Brefは、LaravelなどのPHPアプリケーションをAWS Lambda上で動作させるためのツールです。通常、LambdaはNode.jsやPythonJava、Goといったランタイムを公式にサポートしていますが、PHPは含まれていません。Brefはこのギャップを埋めるため、独自のPHPランタイムを提供し、PHPアプリケーション(例:Laravelアプリケーション)をAWS Lambda上で実行可能にします。

システム構成

システム構成図

今回作成するシステムの構成図は以下の通りです。

  • 静的ファイルはCloudFront経由でS3から取得
  • 動的なリクエストはCloudFrontからAPI Gatewayを介してLambdaに送信し、バックエンドで処理

バックエンドはLaravel + Brefで、フロントエンドはReactで実装してビルドしたものをS3に配置するSPAとして構築しました。

実装手順

実装はバックエンドとフロントエンドに分けて進めます。

バックエンド

LaravelでAPIを実装

api.phpに以下のようなコードを追加し、簡単なレスポンスを返すようにしました(Laravel 11を使用)。

<?php

use Illuminate\Support\Facades\Route;

Route::get('/hello', function () {
    return response()->json(['message' => 'Hello World!']);
});

Brefのセットアップ

brefの公式ドキュメントに従い、Serverless FrameworkのインストールやAWSアクセスキーの設定を行います。今回はbrefというプロファイルを作成し、デプロイに使用しました。

Laravelにbrefをインストールし、デプロイ

composerを使ってbrefをインストールします。

composer require bref/bref bref/laravel-bridge --update-with-dependencies

次に、serverless.ymlをコマンドで生成します。

php artisan vendor:publish --tag=serverless-config

デフォルトのserverless.ymlを編集します。

  • regionap-northeast-1に変更
  • profileに作成したプロファイル名を追加
  • runtimephp-83-xxxに変更(Laravel 11にはPHP 8.3が必要なため)
service: laravel

provider:
    name: aws
    # The AWS region in which to deploy (us-east-1 is the default)
    region: ap-northeast-1
    # Environment variables
    environment:
        APP_ENV: production # Or use ${sls:stage} if you want the environment to match the stage
        SESSION_DRIVER: cookie # Change to database if you have set up a database
    profile: bref

package:
    # Files and directories to exclude from deployment
    patterns:
        - '!node_modules/**'
        - '!public/storage'
        - '!resources/assets/**'
        - '!storage/**'
        - '!tests/**'

functions:

    # This function runs the Laravel website/API
    web:
        handler: public/index.php
        runtime: php-83-fpm
        timeout: 28
        events:
            - httpApi: '*'

    # This function lets us run artisan commands in Lambda
    artisan:
        handler: artisan
        runtime: php-83-console
        timeout: 720 # in seconds
        # Uncomment to also run the scheduler every minute
        #events:
        #    - schedule:
        #          rate: rate(1 minute)
        #          input: '"schedule:run"'

plugins:
  - ./vendor/bref/bref

以下のコマンドでデプロイすると、API GatewayとLambdaが作成されます。

serverless deploy

フロントエンド

Reactアプリケーションを作成

npx create-react-app my-app

ReactからLaravelのAPIを呼び出す機能を実装

App.jsに以下のコードを追加し、LaravelのAPIから取得したデータを画面に表示させます。

import React, { useEffect, useState } from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  // useStateを使ってAPIから取得したデータを保存する
  const [apiData, setApiData] = useState(null);

  // useEffectを使ってコンポーネントのマウント時にAPIリクエストを送信
  useEffect(() => {
    // Laravel APIへのリクエストを送信
    fetch('/api/hello')
      .then(response => response.json())  // レスポンスをJSON形式に変換
      .then(data => {
        setApiData(data);  // APIのデータをstateに保存
      })
      .catch(error => {
        console.error('Error fetching data:', error);
      });
  }, []);  // 空の依存配列により、この効果はコンポーネントが初回レンダリングされたときだけ実行される

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
        {/* APIデータが存在する場合に表示 */}
        {apiData && <p>API Response: {apiData.message}</p>}
      </header>
    </div>
  );
}

export default App;

ReactをビルドしてS3に配置

npm run build
aws s3 sync build/ s3://your-bucket-name

CloudFrontの設定

最後に、CloudFrontを作成し、S3とAPI Gatewayをオリジンとして設定します。

/api/*パスパターンでAPI Gatewayに向くようにビヘイビアを設定し、それ以外はS3に向くようにします。

以上で実装が完了です。CloudFrontのURLにアクセスすると、ReactアプリにLaravelのレスポンスが表示されるようになります。

まとめ

今回の記事では、LaravelとBrefを使用してサーバーレスアプリケーションを構築する方法を紹介しました。Brefを利用することで、AWS Lambda上でLaravelを動作させる環境を簡単に構築できることが分かりました。

株式会社フォトラクションでは一緒に働く仲間を募集しています