Lumen + Nginx + MySQLで簡単なAPIを作成してみた

 PHP 

 Lumen 

 Backend 

作成日:2022/03/30

はじめに

最近、フロントエンドに React、サーバーサイドに Lumen を使って簡単な掲示板を開発しました。 ちなみに、Docker 上で実行しています。

万能で機能がたくさんある Laravel とは違い、軽量版である Lumen はハマりポイントがいくつもあって大変でした。 しかも、Laravel に比べると情報が非常に少ない。。。

中々大変だったので、この記事にまとめてみました!

Lumen, Nginx, MySQL 導入

Docker-compose が使える前提で書いているのでご注意ください

ディレクトリ構成

まず最初に、ディレクトリ構成を見ていきましょう!

├── Docker
│   ├── mysql
│   │   ├── Dockerfile
│   │   ├── conf.d
│   │   │   └── my.conf
│   │   ├── initdb.d
│   │   └── mysql_data
│   ├── nginx
│   │   ├── Dockerfile
│   │   └── conf
│   │       └── default.conf
│   └── php
│       ├── Dockerfile
│       └── php.ini
├── docker-compose.yml
└── var
    └── www
        └── backend

こんな感じにしました。

Docker-compose.yml の編集

Docker-compose.yml は ↓↓↓

version: '3'

services:
  backend:
    container_name: php
    build: ./Docker/php
    volumes:
      - ./var/www/backend:/var/www/backend
    working_dir: /var/www/backend
    links:
      - mysql
    environment:
      DB_PORT: 3306
      DB_HOST: mysql
      DB_DATABASE: test
      DB_USERNAME: root
      DB_PASSWORD: root

  nginx:
    build: ./Docker/nginx
    container_name: web
    volumes:
      - ./Docker/nginx/conf/default.conf:/etc/nginx/conf.d/default.conf
      - ./var/www/backend/public:/var/www/backend/public
    ports:
      - 8080:80
    links:
      - backend

  mysql:
    build: ./Docker/mysql
    container_name: db
    environment:
      MYSQL_DATABASE: coco
      MYSQL_USER: root
      MYSQL_PASSWORD: root
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - ./Docker/mysql/initdb.d:/docker-entrypoint-initdb.d
      - ./Docker/mysql/conf.d:/etc/mysql/conf.d
      - ./Docker/mysql/mysql_data:/var/lib/mysql
    ports:
      - 13300:3306

Dockerfile の設定

各 Dockerfile は以下のように書きました。

FROM  nginx:latest
FROM mysql:8.0.16

Lumen のインストールもあるため、PHP の Dockerfile は少々複雑です。 特に、ハッシュ値には注意が必要です。

FROM php:7.3-fpm
COPY php.ini /usr/local/etc/php/

RUN apt-get update \
  && apt-get install -y zlib1g-dev libzip-dev mariadb-client \
  && docker-php-ext-install zip pdo_mysql

#Composer install
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
#ハッシュ値は更新されるのでhttps://getcomposer.org/download/で確認してください
RUN php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
RUN php composer-setup.php
RUN php -r "unlink('composer-setup.php');"
RUN mv composer.phar /usr/local/bin/composer

ENV COMPOSER_ALLOW_SUPERUSER 1

ENV COMPOSER_HOME /composer

ENV PATH $PATH:/composer/vendor/bin

ついでに、php.ini も。

[Date]date.timezone = "Asia/Tokyo"[mbstring]mbstring.internal_encoding = "UTF-8"mbstring.language = "Japanese"display_errors = On

Nginx の設定

図のように、フロントエンドからリクエストがあった際に、Nginx から Lumen に流れていくように設定していきます。

server {
  listen       80;
  server_name  localhost;
  charset      utf-8;

  root /var/www/backend/public;

  index index.php;

  location / {
    try_files $uri $uri/ /index.php$is_args$args;
  }

  location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass  backend:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include       fastcgi_params;
  }
}

これで Nginx と Lumen を繋げることができました!

MySQL の設定

必ずコンテナを立ち上げる前にこの設定をしてください!

[mysqld]default_authentication_plugin= mysql_native_passwordexplicit-defaults-for-timestamp=1general-log-file=/var/log/mysql/mysqld.log

Lumen と MySQL の v8 は相性が悪いみたいで、この設定をしないと Lumen と MySQL を接続できません。 詳しくは、こちらの記事を参照。

ここで、コンテナを立ち上げます。

$ docker-compose up -d

そして、MySQL のコンテナに入りましょう。

$ docker-compose exec mysql

MySQL 起動

$ mysql -u root -p

 docker-compose.yml で設定したパスワードを入力して MySQL を触れるようになります。 続いて、DB の作成

mysql> CREATE DATABASE test;

 $ exit を 2 回打って MySQL とコンテナから出ましょう。

Lumen の設定

最初に

 /backend/bootstrap/app.php 

// $app->withFacades();
// $app->withEloquent();

のコメントアウトを外しておいてください。

Migration

まずは、以下のコマンドで Lumen のコンテナに入っていきます。

docker-compose exec backend bash

続いて、

$ php artisan make:migration create_articles_table --create=articles

とすると、 /backend/database/migrations/タイムスタンプ_create_articles_table.php が生成されます。 この タイムスタンプ_create_articles_table.php を以下のように編集します。

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateArticleTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tests', function (Blueprint $table) {
            $table->increments('id');
       ////////// ↓↓↓追加↓↓↓ ///////////
            $table->string('name');
            $table->text('comment');
       ////////////////////////////////
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('tests');
    }
}

編集後、以下のコマンドを実行。

$ php artisan migrate

ここで、 $ exit のコマンドで一回コンテナから出ます。 その後、MySQL のコンテナに入ってデータベースがあるか確認してみてください。 そして、適当にデータを INSERT しておきましょう。

mysql> INSERT INTO tests (name, comment, created_at, updated_at) VALUE
    ('testman1', 'HELLO!', NOW(), NOW()),('testman2', 'HELLO!', NOW(), NOW()),

その後、ログアウトして、コンテナから出てください。

Model の作成

 backend/app/ に新しく Tests.php を作成してください。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Tests extends Model
{
  protected $table = 'tests';
  protected $fillable = ['name', 'comment'];
}

Route の設定

 backend/routes/web.php でルーティングを設定できます。 ここに以下のルートを追加してください。

$router->group(['prefix' => 'api/v1'], function() use ($router)
{
  $router->get('tests', 'TestsController@tests');
}

Controller の作成

 backend/app/Http/Controllers に新しく TestsController.php を作成して、以下のように編集してください。

<?php
namespace App\Http\Controllers;
use App\Tests;

class TestsController extends Controller
{
  public function tests() {
    return response()->json(Tests::all());
  }
}

以上で API の基礎的な設定が終わりです!

API の確認

 http://localhost:8080/api/v1/tests に行くと、DB の内容が表示されていると思います。