Web API 作成において心得たいことまとめ

Web API 作成において心得たいことまとめ

最近読んだ書籍「Web API The Good Parts」について個人的に心に留めておきたいことをまとめます. なお, 本書籍は発行年2014年と今となっては若干古いため, 現在では古い情報もあることを念頭において読み進めました.

Web API The Good Parts

そのため, 本記事のまとめも今では古いノウハウがあるかもしれません. そういった情報に対してはツッコミをいただけると幸いです.

だいたい, リクエスト, レスポンス, その他といった感じで大まかに3つのセクションにまとめます.

2.2.1 などの数値はそのノウハウが書籍に記載されている章番号です.

リクエストとエンドポイント関連

主に2章の内容.

URI でなんとなく使い方の想像がつく

ドキュメントとかいちいち見たくないため. http://example.com/v1/user/123 だったら ID 123 のユーザーを取得するみたいに容易に 想像がつく URI が理想.

URI に大文字小文字が混ざっていない

基本はすべて小文字を使用する. ホスト名が大文字小文字を無視するため, ホスト部のルールに足並みを揃える.

エンドポイントには複数形の名詞

2.4.1.1

  • users, friends, updates など
  • 集合を表しているものは複数形のほうが適切であるという考え
  • そもそもなぜ名詞なのか?
    • URIがそもそもリソースを表すものであるため
    • そして HTTP のメソッドが動詞を表す

エンドポイントの単語のつなぎは「ハイフン」

2.4.4

  • 区切り候補
    • キャメルケース
    • スネークケース
    • スパイナルケース
  • Google がハイフンを推奨しており SEO 的によいっぽい
  • アンダースコアだとリンクアドレスに下線が引かれて重なって見づらい
  • URIホスト部はハイフンは許可されているがアンダースコアは使えず、大文字小文字の区別がないためホスト部とルールを統一するとハイフンとなる
  • 実際のところ最も良いのは極力単語を繋げないこと
    • パスで区切る
    • 短い表現を目指す
    • クエリパラメータにする
  • しかし割と好みなので、別にアンスコ、キャメルケースでもよい

一括取得系は絞り込みも対応

2.5

GET: /users/ とか

一括取得系のエンドポイントはクエリパラメータを利用して絞り込み 取得などできるとよいかも.

クエリパラメータとパスの使い分け

2.5.5

パラメータをクエリパラメータにするかパスに入れるかの使い分け.

クエリパラメータは以下のような感じのパスの後に?hoge=123などがつく形式.

http://example.com/v1/user/123?hoge=123&fuga=xyz

パスに入れるとは ID 123 のユーザーを取得したい場合は以下のように ID をパスに入れる形式.

http://example.com/v1/user/123

リソースを指定する場合にどちらを採用するかの判断基準は以下.

① 一意なリソースを表すのに必要な情報かどうか

URI がそもそもリソースを表すものであるため, 参照したい情報が一意に決まる場合はパスにしたほうがよい.

② 省略しても良いようなパラメータはクエリにする

メソッド

PUT と PATHCH はどちらも更新系のメソッドだが具体的な使い分けについて.

  • PUT
    • 2.3.3
    • リソースを完全上書きする場合に使用
    • 送信するデータでもともとのリソースを完全に上書きする
  • PATCH
    • 2.3.5
    • リソースの一部を修正する場合に使用

エンドポイントの共通部分にバージョンを付与する

2.7

以下の v1 のような感じ.

http://example.com/v1/xxx

レスポンス関連

レスポンスの内容をユーザーが選べるようにする

3.3.1

ユーザーがほしい情報だけを選べるような作りにする. (名前がほしいだけなら名前だけとか) ほしくない情報が含まれるとデータサイズ的にも無駄になってしまう.

クエリパラメータで指定できるようにする.

http://example.com/v1/users/123?fields=name,age

レスポンスデータは配列ではなくなるべくオブジェクトで?

3.3.4

レスポンスデータに配列を使用するかオブジェクトで配列を包むかで 迷った場合はオブジェクトに統一するほうがややオススメ.

  • レスポンスデータが何を示しているのかわかりやすくなる
  • レスポンスデータをオブジェクトに統一できる
    • クライアント側で処理を共通化できる
  • JSONインジェンクションのリスクが軽減する

読み込んだJSONファイルがオブジェクトの場合, トップレベルにブレースがきて JavaScriptの構文としておかしいためJSONインジェクションを防ぐ可能性がやや上がる.

単/複数形に気をつける

3.4.1

データが複数(配列)になる可能性があるなら「複数形」, 1つだけなら単数形というかたちできちんと使い分ける.

日付はRFC3339を使用する

3.4.3

RFC3339 とは以下のようなフォーマットの日付.

2015-10-15T11:30:22+09:00

  • 数ある日時を表すフォーマットの問題を解決したフォーマットだから
  • 読みやすく使いやすいを目指したインターネット上で用いる標準形式だから
  • 冗長な表現もない
    • 他であるような日付と曜日両方を含むなど

ただし, HTTPヘッダの Date や Expires などには使用できない...

エラー時のステータスコードは適切に

3.6.1

ちゃんとステータスコードでエラーの状態を示す. リクエストが成功していないのに200番台を返すなどはしない.

クライアントライブラリとかでステータスコードを見て処理を分岐するものなども あるため, ちゃんと作法に従う.

データをエンベロープ(封筒)で包まない

3.3.2

エンベロープとはAPI的にはすべてのデータを同じ構造でくるむこと.

「HTTPの仕様をフル活用する」にも書いているがそもそもHTTPヘッダがエンベロープなので冗長になる.

その他

HTTPの仕様をフル活用する

4

  • HTTPヘッダ
  • ステータスコード
  • キャッシュ
    • クライアント側にキャッシュをさせたい/させたくないなどHTTPヘッダである程度コントロールできる
    • Cache-Contorol
      • キャッシュしてほしくない場合は no-cache, no-store
    • Vary
      • URI以外にデータを一意に特定するリクエストヘッダを指定する
      • URIが同じでもVaryで指定したヘッダに変化があった場合キャッシュではなくデータをとりに行く
  • メディアタイプ

Laravel : Docker + VSCode でデバッガ環境構築

Laravel : Docker + VSCode でデバッガ環境構築

目的

Docker コンテナ上で動作してる Laravel を xdebugデバッグできる環境を構築する.

環境

  • macOS
  • Docker
    • 20.10.12
  • Laravel
    • 9.21.5
  • PHP
    • 8.1.8
  • Composer
    • 2.3.10
  • MySQL
    • 8.0.29

手順

Docker コンテナを使用した環境構築は完了している前提で記事を書きます. Docker を使ったサーバー構築手順は以下の記事にまとめています.

https://kita127.hatenablog.com/entry/2022/10/02/145614

編集するファイルは以下の4ファイル.

  • Dockerfile
  • php.ini
  • docker-compose.yaml
  • .vscode/launch.json

Dockerfile

サーバー用のコンテナの Dockerfile に xdebug をインストールする記述を追加する.
pecl install xdebugxdebug をインストールする.
docker-php-ext-enable xdebugxdebug を有効化する.

# xdebug のインストール
RUN pecl install xdebug \
  && docker-php-ext-enable xdebug

php.ini

コンテナサーバーに配置する php.ini に以下を追加する. 9012 は xdebug のポート

[xdebug]
xdebug.mode = debug
xdebug.start_with_request = yes
xdebug.client_host = "host.docker.internal"
xdebug.client_port = 9012
xdebug.log = "/var/log/xdebug.log"

docker-compose.yaml

サーバーコンテナの volumes に xdebug のログをマウントするよう- ./log:/var/log を追加する. 左側はローカルのログ置き場のパス, 右側は php.ini で設定した xdebug のログのディレクトリ.

    volumes:
      - ./webapp:/var/www/html
      - ./docker/apache/php.ini:/usr/local/etc/php/php.ini
      - ./log:/var/log

launch.json

portxdebug のポート 9012 を設定する
pathMappings は左に Docker コンテナ上に配置している Laravel アプリケーションのパス
右にローカルで作業している Laravel アプリケーションのパスを設定する.

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9012,
            "pathMappings": {
                "/var/www/html": "${workspaceFolder}/webapp"
            }
        }
    ]
}

試す

以上で xdebug を使用する環境構築は完了. 任意の箇所にブレイクポイントを設定し, start debugging をすればステップ実行や変数の状態の確認などができるようになる.

参考記事

以下の記事を参考にさせていただきました.

https://maasaablog.com/development/backend/php/laravel/2308/

Docker + Apache + Laravel で Web アプリケーションつくる

Docker + Apache + Laravel で Web アプリケーションつくる

やりたいこと

Laravel 製の Web アプリケーションを作成し, 自宅サーバ PC にデプロイしたい. とりあえず, 自宅のプライベートネットワーク内だけの運用を想定しているがそのうち VPN などで外部からもアクセスできるようにしたいかも.

デプロイ作業を楽にしたい&環境構築とかでカオスになりたくないため Web サーバーやデータベースは Docker コンテナを利用し, 各コンテナを連携させる構成とする.

Docker コンテナを利用した Laravel 開発には Sail があるが, Apache への載せ替え方がわからなかったのと, Docker の勉強も兼ねてコンテナ連携の構築から自前で作成する.

また, 自身の勉強も兼ねているため各技術要素についてなるべく詳細に残していく予定.

要件

  • Web サーバーとデータベースはそれぞれ Docker コンテナ化し連携する
  • Web サーバーは Apache を使用する
  • データベースは MySQL を使用する
  • Web アプリケーションは PHPフレームワーク Laravel を使用し作成する

本記事の内容

本記事では要件のうち基盤づくりまで, つまり Docker で ApacheMySQL のコンテナ を作成・連携, Apache コンテナ上に構築した Laravel から簡単なレスポンスをクライアント返すところまでを作る.

また, 作成したプロジェクトのリポジトリは以下.
https://github.com/kita127/docker-apache-example

環境

ホストPCで使用する各種ツールのバージョンは以下. 開発は Mac PC で行う.

サーバ PC は準備中. おそらく ubuntu を採用する見込み. 現段階ではホストPCのみで開発をすすめる.

環境構築

必要なアプリケーションを Homebrew を使ってインストールする.

# brew install --cask docker
# brew install php
# brew install composer

構成

今回作成するプロジェクトの構成は以下の通り.

プロジェクトトップ
├── docker/
│      ├── apache/
│      │      ├── Dockerfile
│      │      ├── config/
│      │      │      └── 000-default.conf
│      │      └── php.ini
│      └── db/
│              ├── Dockerfile
│              └── initdb.d/
│                      └── master.sql
├── docker-compose.yaml
└── webapp/
  • docker/
    • 各コンテナの Dockerfile やコンフィグ系のファイルを格納する
  • docker/apache/
    • Apache コンテナの設定や Dockerfile など
    • Web サーバの設定である .conf ファイルもここで管理する
    • php.ini もここで管理
  • docker/db/
    • DB(MySQL) コンテナの Dockerfile や設定ファイル等を管理
    • コンテナ起動時に実行される SQL ファイル(master.sql)も管理
  • docker-compose.yaml
    • コンテナの連携のための Docker Compose 設定ファイル
  • webapp/
    • Web アプリケーション(Laravel プロジェクト)

手順

Docker の構築

docker-compose.yaml の作成

Webサーバと DB のコンテナを作成する設定をつくる. 構成に記載の docker-compose.yaml を以下の通り作成.

version: '3'

services:
  apache:
    container_name: apache
    build:
      context: .
      dockerfile: ./docker/apache/Dockerfile
    ports:
      - 80:80
    environment:
      COMPOSER_ALLOW_SUPERUSER: 1
    volumes:
      - ./webapp:/var/www/html
      - ./docker/apache/php.ini:/usr/local/etc/php/php.ini
    depends_on:
      - db
    networks:
      - net1
  db:
    container_name: db
    build:
      context: .
      dockerfile: ./docker/db/Dockerfile
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_USER: docker
      MYSQL_PASSWORD: docker
      TZ: 'Asia/Tokyo'
    networks:
      - net1
    ports:
      - 3306:3306
networks:
  net1:
  • services 以下に apache コンテナと db コンテナを作成
  • services.apache
    • Apache のコンテナ
    • image の指定やコンテナ独自の設定は Dockerfile で行う
    • container_name
      • コンテナの名前
      • 各コンテナはこの名前で IP の名前解決がされるためコンテナ名での通信が互いに可能となる
        • 例えば apache コンテナ内で $ ping dbdb コンテナに対して ping を投げたりもできる
    • build
      • ビルド時の設定
      • context
        • ビルドする際のビルドコンテキストをプロジェクトトップとする
        • コンテナがビルドされる際のカレントディレクトリを決める
        • Dockerfile にパスを記述する際の基準となるパス
          • この場合, 相対パスを記述する際はプロジェクトトップがカレントとなる
    • dockerfile
      • ビルド時の Dockerfile ファイルを指定
    • ports
      • ホストの TCP 80 番 ポートへコンテナの TCP 80 番ポートをフォワード
    • environment
      • コンテナに環境変数 COMPOSER_ALLOW_SUPERUSER を 1 で設定
        • root ユーザへの Composer インストールを許可するとのこと
        • Do not run xxx のような警告が出るらしくそれを抑えるため設定
    • volumes
      • Laravel プロジェクト(webapp/)を apache コンテナの /var/www/html にマウント
      • ローカルの php.ini をコンテナにマウントする
        • - ./docker/apache/php.ini:/usr/local/etc/php/php.ini
    • depends_on
      • Laravel から DB にアクセスするため db コンテナの起動後に apache コンテナを起動する
      • なくても大丈夫な気もする・・・
    • net1
      • apache コンテナと db コンテナは互いにやりとりする必要があるため同一ネットワーク net1 に属させる
  • services.db
    • DB のコンテナ
    • environment
      • MYSQL_ROOT_PASSWORD
        • root ユーザーのパスワード
    • port
      • ホストの TCP 3306 番 ポートへコンテナの TCP 3306 番ポートをフォワード
      • Sequel などの MySQL 用の GUI ツールを使用する際, ホストから 3306 ポートでコンテナの MySQL を操作できる
    • 他の設定値については services.apache の内容を参照
  • networks.net1
    • apache コンテナと db コンテナで通信するためのネットワークを定義

apache コンテナの Dockerfile の作成

プロジェクトトップ/docker/apache/ に以下の apache コンテナ用の Dockerfile を作成する.

FROM php:8.1-apache-bullseye

# apt install iputils-ping net-tools で ping を導入
RUN apt-get update \
 && apt-get install -y zlib1g-dev libzip-dev unzip vim iputils-ping net-tools sudo\
 && docker-php-ext-install zip

# node と npm をインストール
RUN apt-get install -y gnupg
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash -\
 && apt-get install -y nodejs\
 && npm install npm@8.12.1 --global


# a2emod rewrite をして apache に rewrite モジュールを追加
# これをしないと Laravel でルート以外にアクセスできない
RUN a2enmod rewrite

# docker php には mysql 用のドライバが未インストールのため追加する
RUN docker-php-ext-install pdo_mysql

COPY --from=composer:2.4.1 /usr/bin/composer /usr/bin/composer

ADD docker/apache/php.ini /usr/local/etc/php/

# Apache の conf は seites-available に作成し
# a2ensite コマンドでシンボリックリンクを sites-enabled に作成する
ADD docker/apache/config/000-default.conf /etc/apache2/sites-available/
RUN a2ensite 000-default

WORKDIR /var/www/html

COPY ./webapp /var/www/html

RUN chown www-data storage/ -R \
 && composer install\
 && npm install
  • FROM
    • 元となる Docker イメージの指定
    • ホスト環境と同じ PHP 8.1 系をセレクト
    • Docker Hub の php イメージ, 8.1-apache-bullseye タグを指定
    • 8.1-apache-bullseyeDebian Apachemod_php が含まれたタグ
  • RUN apt-get update ....
    • コンテナ起動時にパッケージ情報のアップデートと必要なパッケージをインストール
    • iputils-pingnet-tools
      • ping を利用するためインストール
      • コンテナ間の疎通確認とかで使用したいがデフォルトではインストールされていないため追加
    • docker-php-ext-install zip
  • node と npm のインストールの詳細についてはnode/npmのインストール詳細を参照
  • RUN a2enmod rewrite
    • Apacherewrite モジュールを追加する
    • Laravel でのルーティングにはこのモジュールの有効化が必要
  • RUN docker-php-ext-install pdo_mysql
    • Docker の PHP コンテナには MySQL 用のドライバがインストールされていないため追加する
  • COPY --from=composer:2.4.1 /usr/bin/composer /usr/bin/composer
    • composer:2.4.1 イメージをビルドし作成した composer の実行形式をコンテナの /usr/bin/composer にコピーしているぽい
    • Composer のバージョンはホスト環境と合わせる
    • COPY --from=name src dest
      • FROM <image> as <name> として名前をつけて構築したステージをコピー元として指定できる
      • composer:2.4.1 を指定しているので名前つけをしたステージ以外にも image を直接指定もできるぽい?
      • 詳細は Docker Hub の Composer イメージのページや Dockerfile リファレンスの COPY を参照
  • ADD docker/apache/php.ini /usr/local/etc/php/
    • PHP の設定ファイル(php.ini)をコンテナの然るべき場所に置く
  • ADD docker/apache/config/000-default.conf /etc/apache2/sites-available/
  • RUN a2ensite 000-default
    • docker/apache/config にある Apache のコンフィグファイル(000-default.conf)を sites-available に置く
    • 大元のコンフィグファイルである apache2.conf では sites-enabled/ のみ IncludeOptional ディレクティブにより有効化される. sites-available/ は有効化されない
    • sites-available に置いたコンフィグファイルのシンボリックリンクsites-enabled に置くことにより sites-available/ 内の任意のコンフィグを有効にする
    • シンボリックリンクの作成は直接作成して sites-enabled においても構わないが, a2ensite コマンドで作成可能
    • https://nanbu.marune205.net/2021/12/debian-apache2-dir.html
  • WORKDIR /var/www/html
  • COPY ./webapp /var/www/html
    • Web アプリケーション(Laravelプロジェクト)をコンテナの /var/www/html にコピーする
  • RUN chown www-data storage/ -R \
    • www-dataApache がデフォルトで通常操作に使用するユーザー
    • www-data がアクセスできるファイルに Apache もアクセスできる
    • Laravel プロジェクトの storage フォルダ以下の所有者を www-data に変更する
  • composer install
    • composer.lock の内容でパッケージをインストール
node/npmのインストール詳細

Laravel でアプリケーションを作成する場合, 使用するパッケージによっては Node および npm を使用するため Docker 環境内に導入しておく. 導入に際してDockerでphpコンテナとかにnpmをインストールするときのメモを参考にさせていただきました.

Docker コンテナ上に構築される Debian のパッケージマネージャでは Node のバージョンが古かったり, npm が同梱されていなかったり等あるらしいので NodeSource Node.js Binary Distributionsからインストールする.

リンク先の記載内容を元に任意の Node をインストールする.
今回は Node 本体としては Debian 向けのバージョンは 18 を選択(curl -fsSL https://deb.nodesource.com/setup_18.x | bash -).

Node インストール後, 任意のバージョンの npm を取得するため npm でバージョン 8.12.1 の npm をインストール(npm install npm@8.12.1 --global).

# node と npm をインストール
RUN apt-get install -y gnupg
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash -\
 && apt-get install -y nodejs\
 && npm install npm@8.12.1 --global

Apache のコンフィグファイルの作成

Apache サーバのコンフィグファイル プロジェクトトップ/docker/apache/config/000-default.conf を以下の通り作成する.

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html/public
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
  • VirtualHost
  • ServerAdmin
    • サーバがクライアントに送るエラーメッセージに含めるアドレス
    • プライベートに使用するウェブサイトのため適当に設定
  • ErrorLog
    • エラーログファイルの指定
    • APACHE_LOG_DIR環境変数はコンテナの /etc/apache2/envvars に定義されている
  • CustomLog
    • クライアントのアクセスログを記録するファイルとフォーマットを指定する
    • 第2引数の combinedLogFormat ディレクティブで名前つけされたフォーマット
      • combinedapache2.conf に以下の通り定義されている
      • LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
    • 本ディレクティブは mod_log_config モジュールの機能

php.ini の作成

PHP の設定ファイル プロジェクトトップ/docker/apache/php.ini を以下の通り作成. とりあえず, タイムゾーンと言語に関する設定だけ.

[Date]
date.timezone = "Asia/Tokyo"

[mbstring]
mbstring.language = "Japanese"

db コンテナの Dockerfile の作成

プロジェクトトップ/docker/db/ に以下の db コンテナ用の Dockerfile を作成する.

FROM mysql:8.0.30

# docker-entrypoint-initdb.d にある SQL ファイルがコンテナ起動時に実行される
COPY ./docker/db/initdb.d /docker-entrypoint-initdb.d
  • FROM mysql:8.0.30
    • MySQL イメージの 8.0.30 タグを使用する
  • COPY ./docker/db/initdb.d /docker-entrypoint-initdb.d
    • docker/db/initdb.d フォルダをコンテナの /docker-entrypoint-initdb.d にコピーする
    • /docker-entrypoint-initdb.d フォルダにある SQL ファイルがコンテナ起動時に実行される

プロジェクトトップ/docker/db/initdb.d/ に以下の db コンテナ起動時に実行される master.sql を格納する.

キャラクタ設定をして master スキーマを作成している.

SET CHARACTER_SET_CLIENT = utf8;
SET CHARACTER_SET_CONNECTION = utf8;

CREATE DATABASE `master`;

以上で ApacheMySQL のコンテナ作成のための準備は完了.

Laravel プロジェクトの作成

それでは Laravel プロジェクトを作成する.

今回は Docker 環境内で Laravel を動かすため, Docker 側から Laravel プロジェクトをインストールする.

プロジェクト直下で docker-compose up -d --build を実行しコンテナを立ち上げる. その際 Dockerfile 内の RUN chown www-data storage/ -R によってまだ作成していない Laravel プロジェクト内の storage ディレクトリにアクセスしようとしエラーとなるので一旦 docker/apache/Dockerfile の以下部分の記述はコメントアウトしておく.

#RUN chown www-data storage/ -R \
# && composer install

Docker コンテナが問題なく立ち上がったら docker-compose exec apache bashapache コンテナ内に入る.

/var/www/ に移動し以下コマンドを実行し html ディレクトリに Laravel プロジェクトを作成する.

$ composer create-project laravel/laravel html

問題なく作成されたら exit しコンテナから出る.

その後, コメントアウトした Dockerfile の記述を元に戻し, 一旦 docker-compose をダウン(docker-compose down --rmi all --volumes --remove-orphans), 再度アップ(docker-compose up -d --build) し再構築する.

この状態でブラウザから http://localhost:80 にアクセスし, Laravel のトップページが表示されれば問題なし.

Laravel から DB にアクセスする準備

とりあえず, db コンテナと連携できるかの確認のため捨てテーブルを作る. テーブル生成用のマイグレーションファイルを作成する. 以下のコマンドを実行.

$ php artisan make:migration create_hoges_table

database/migrations/yyyy_mm_dd_xxxx_create_hoges_table.php が生成される.

確認用なのでとりあえずデフォルトのままでOK.

Eloqent モデルを作成する. 以下のコマンドを実行.

$ php artisan make:model Hoge

webapp/app/Models/Hoge.php が作成される.

次にコントローラを以下のコマンドで作成.

$ php artisan make:controller HogeDir/HogeController --invokable

webapp/app/Http/Controllers/HogeDir/HogeController.php が作成される.

とりあえず動作確認のため, hoges テーブルからレコードを取得し先頭要素の id をビューに渡すだけの処理を実装.

<?php

namespace App\Http\Controllers\HogeDir;

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

class HogeController extends Controller
{
    /**
     * Handle the incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function __invoke(Request $request)
    {
        $ls = Hoge::all();
        return view('hoge.index', ['hoge' => $ls[0]->id]);
    }
}

webapp/resources/views/hoge/index.blade.php を作成する. これも確認のためだけなので $hoge を表示する簡易な表示のみ.

<!doctype html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0,
          maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>アプリタイトル</title>
</head>

<body>
    <h1>アプリボディ</h1>
    <p>{{ $hoge }}</p>
</body>

</html>

.env の変更

.env は DB に関する設定だけ以下の通り変更する. DB_HOST にはデータベースサーバの IP を設定するが, Docker のネットワーク内であれば コンテナ名で名前解決されるため, db で OK. ただし, ホストからはコンテナ名では IP の名前解決はできないため ホストで動かした Laravel からは DB にはアクセスできない. docker-compose.yaml で別途コンテナに IP アドレスを 付与してやり, そちらを DB_HOST に設定すればホストで動かした Laravel からでも DB にアクセスできる気がするが, 基本的に apache コンテナで動かすつもりなので今の所やらない.

...

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=master
DB_USERNAME=root
DB_PASSWORD=secret

...

Web サーバ(Apache)の確認

ここまでで準備が整ったのでそれぞれのコンテナの動作確認をする.

まずはコンテナを生成するためプロジェクトトップで以下のコマンドを実行. -d でデーモン起動(detachの略らしいけど).

$ docker-compose up -d

ブラウザで http://localhost:80/ にアクセスし Laravel のページが表示されれば問題なく apache コンテナが起動していることを確認できる.

DB(MySQL)の確認

Laravel から DB にアクセスできるか確認する.

そのまえに, DB アクセスのための下準備が完了していないためそちらを終わらせる.

まず, master スキーマが生成されていることを確認する. db コンテナに入る.

$ docker-compose exec db bash

以下のコマンドを実行. docker-compose.yaml に設定している MySQL のパスワードを入力する.

# mysql -u root -p
# パスワードを入力

show databases;master スキーマが生成されていることを確認する.

+--------------------+
| Database           |
+--------------------+
| information_schema |
| master             |
| mysql              |
| ......             |
| ......             |

exit;mysql を終了, さらに exit しコンテナからも出る.

次に apache コンテナに入る.

$ docker-compose exec apache bash

まずは apache コンテナで MySQL 用のドライバがインストールされているか確認する. 以下のコマンドを実行し pdo_mysql が確認できれば OK.

$ php -m | grep mysql
mysqlnd
pdo_mysql

Laravel プロジェクトをマウントしたディレクトリ(/var/www/html)に移動する(おそらくコンテナに入った時点でそのディレクトリのはず).

$ pwd
/var/www/html

マイグレーションを実行し hoges テーブルを作成する.

$ php artisan migrate

exitapache コンテナを出る. 再度, db コンテナに入る.

$ docker-compose exec db bash

hoges テーブルが作成されていることを確認. 表示用のダミーデータを適当に追加する.

$ mysql -u root -p
パスワード入力

mysql> use master;

mysql> show tables;
+--------------------+
| Tables_in_master   |
+--------------------+
| ......             |
| hoges              |
| ......             |
| ......             |
| ......             |


mysql> insert into hoges (id) values (1);

mysql> select * from hoges;
+----+------------+------------+
| id | created_at | updated_at |
+----+------------+------------+
| 1  | NULL       | NULL       |
+----+------------+------------+

db コンテナから抜ける.

ブラウザから http://localhost:80/hoge にアクセスしテーブルに追加したレコードの id が表示されていることを確認できれば 問題なく apache コンテナ上の Laravel から db コンテナの MySQL にアクセスできている.

以上で Docker + Apache + Laravel での最低限の環境が完成.

その他

  • Docker コンテナの停止と削除は以下のコマンドで実施
    • $ docker-compose down --rmi all --volumes --remove-orphans
      • --rmi all
        • 使用したイメージも全て削除する
      • --volumes
        • volume を全削除
      • --remove-orphans
        • Compose ファイルで定義されていないコンテナも削除する
  • apache コンテナ内での php artisan migrate はホストから docker exec コマンドでも OK
    • $ docker exec apache php artisan migrate
  • データベースへのアクセスをコマンドでやるとめんどくさいので GUI アプリを使用すると吉
    • 自分は Sequel Ace を使用
    • localhost の ポートフォワードしているポートから使用できる

出典

作成にあたり以下の記事を参考にさせていただきました.

Laravel : 画像のアップロードと表示

Laravel : 画像のアップロードと表示

環境

  • macOS Big Sur
    • 11.6.5
  • Docker
    • 20.10.12
  • Laravel
    • 9.21.5
  • PHP
    • 8.1.8
  • Composer
    • 2.3.10
  • MySQL
    • 8.0.29

参考

画像のアップロード

画像をアップロードし, DB に保存する.
画像は別のストレージに保存し, DB には画像のファイル名のみを保存する.

画像用テーブルを作成する

$ sail artisan make:migration createImagesTable

スキーマ設定に画像のファイルパスを文字列で保存する name を追加する.

20XX_XX_XX_XXXXX_create_images_table.php

<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('images', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }

    ...省略

};

マイグレーションを実行する

マイグレーションを実行し DB にテーブルを作成する.

$ sail artisan migrate

画像用の Eloquent モデルを作成する

画像用の Eloquent モデルを生成. 中身はデフォルトのままで OK.

$sail artisan make:model Image

シンボリックリンクを作成する

画像は storage ディレクトリに保存される. storage ディレクトリは外部からアクセスできないため storage/app/publicpublic から参照できるようシンボリックリンクを作成する.

$ sail artisan storage:link

画像用のコントローラを作成

GET のコントローラ

$ sail artisan make:controller --invokable Image/IndexController

アップロード用 POST のコントローラ

$ sail artisan make:controller --invokable Image/UploadController

ルーティングの追加

<?php

...省略

Route::get('/', function () {
    return view('welcome');
});


Route::get('/image', \App\Http\Controllers\Image\IndexController::class)->name('image.index');
Route::post('/image/upload', \App\Http\Controllers\Image\UploadController::class)->name('image.upload');

...省略

GET コントローラの編集

とりあえず Blade の表示だけ.

app/Http/Controllers/Image/IndexController.php

<?php

namespace App\Http\Controllers\Image;

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

class IndexController extends Controller
{
    /**
     * Handle the incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function __invoke(Request $request)
    {

        return view('image.index');
    }
}

Blade の編集

フォームを作成する.
画像アップロードには enctype="multipart/form-date" が必要.

resources/views/image/index.blade.php

<x-layout title="TOP | 画像サンプル">
    <x-layout.single>
        <h2 class="text-center text-blue-500 text-4xl font-bold mt-8 mb-8">
            画像サンプル
        </h2>
    </x-layout.single>
    <div>
        <form action="{{ route('image.upload') }}" method="post" enctype="multipart/form-data">
            @csrf
            <input type="file" name="image">
            <input type="submit" value="画像アップ">
        </form>
    </div>
</x-layout>

リクエストの作成(バリデーション・リクエスト取得)

バリデーションとリクエストの取得のためリクエストを作成する.

$sail artisan make:request Image/CreateRequest.php

CreateRequest.php が生成されるので編集する.
authorize はログインを要求するか否かの設定. システムに合わせて適宜編集.
rules にバリデーションルールを追加. nameimage の要素に対して 「必須」「画像」「拡張子」「サイズ」のルールを追加.

加えて画像取得用のメソッド image を追加. ファイルの取得は $this->file() で行う.

app/Http/Requests/Image/CreateRequest.php

<?php

namespace App\Http\Requests\Image;

use Illuminate\Foundation\Http\FormRequest;

class CreateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules()
    {
        return [
            //
            'image' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048'
        ];
    }

    public function image()
    {
        return $this->file('image');
    }
}

画像保存処理作成

app/Services/ に任意のサービスクラスを作成する.
今回は ImageService.php で作成.

ストレージへの保存と Model を使用した DB へのファイル名保存処理を実装する.
DB に保存するファイル名はハッシュ.

app/Services/ImageService.php

<?php

namespace App\Services;

use App\Models\Image;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class ImageService
{

    public function saveImage($image)
    {
        Storage::putFile('public/images', $image);
        $imageModel = new Image();
        $imageModel->name = $image->hashName();
        $imageModel->save();
    }
}

POST コントローラの編集

POST 用のコントローラに画像のリクエスト取得処理と保存処理を実装.

app/Http/Controllers/Image/UploadController.php

<?php

namespace App\Http\Controllers\Image;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Services\ImageService;
use App\Http\Requests\Image\CreateRequest;

class UploadController extends Controller
{
    /**
     * Handle the incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function __invoke(CreateRequest $request, ImageService $imageService)
    {
        //
        $image = $request->image();
        $imageService->saveImage($image);
        return redirect()->route('image.index');
    }
}

以上でストレージと DB にアップロードした画像が保存される.

画像の表示

アップした画像を表示する.

DB からファイル名取得

ファイル名を取得する処理を追加(Image::all()).

app/Services/ImageService.php

<?php

namespace App\Services;

use App\Models\Image;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class ImageService
{

    public function saveImage($image)
    {
        Storage::putFile('public/images', $image);
        $imageModel = new Image();
        $imageModel->name = $image->hashName();
        $imageModel->save();
    }

    public function getImages()
    {
        return Image::all();
    }
}

GET 用のコントローラに画像取得処理追加

GET 用のコントローラに DB から画像のファイル名を取得する処理を追加.
取得した画像のファイル名を Blade に渡す.

app/Http/Controllers/Image/ImageController.php

<?php

namespace App\Http\Controllers\Image;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Services\Imageservice;

class IndexController extends Controller
{
    /**
     * Handle the incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function __invoke(Request $request, Imageservice $imageService)
    {
        //
        $images = $imageService->getImages();

        return view('image.index')->with('images', $images);
    }
}

Blade に画像表示処理追加

resources/views/image/index.blade.php

<style>
    .image {
        width: 120px;
        height: 120px;
    }
</style>

<x-layout title="TOP | 画像サンプル">
    <x-layout.single>
        <h2 class="text-center text-blue-500 text-4xl font-bold mt-8 mb-8">
            画像サンプル
        </h2>
    </x-layout.single>
    <div>
        <form action="{{ route('image.upload') }}" method="post" enctype="multipart/form-data">
            @csrf
            <input type="file" name="image">
            <input type="submit" value="画像アップ">
        </form>
    </div>
    <div>
        <ul>
            @foreach ($images as $image)
                <li>
                    <div class="image">
                        <img src="{{ asset('storage/images/' . $image->name) }}">
                    </div>
                </li>
            @endforeach
        </ul>
    </div>
</x-layout>

以上で http://localhost/image にアクセスするとアップロードした画像が表示される.

画像の削除

画像の消去は以下.

use App\Models\Image;
use Illuminate\Support\Facades\Storage;


...省略

// 対象画像のモデルを取得
$image = Image::where('id', $imageId)->firstOrFail();

$filePath = 'public/images' . $image->name;
// ファイルをストレージから削除
if (Storage::exists($filePath)) {
    Storage::delete($filePath);
}

// DB から対象の画像を削除
$image->delete();

Laravel : 入力のバリデーション

Laravel : 入力のバリデーション

POST メソッドの実装と入力のバリデーションについて

環境

  • macOS Big Sur
    • 11.6.5
  • Docker
    • 20.10.12
  • Laravel
    • 9.21.5
  • PHP
    • 8.1.8
  • Composer
    • 2.3.10
  • MySQL
    • 8.0.29

参考

概要

以下についてまとめる.

  • POST メソッド
  • バリデーション
  • Route に名前をつける

実装

バリデーションクラスの作成

バリデーション用の FormRequest クラスの作成.

$ sail artisan make:request HogeDir/HogeRequest

app/Http/Requests/HogeDir/HogeRequest.php が作成される.

誰でもリクエストできるようにする場合は authorize メソッドの戻り値を true にする.

public function authorize()
{
    return true;
}

バリデーションルールの設定

バリデーションのルールを設定する.

以下は設定例.

  • 入力が必須(required)
  • 140文字制限(max:140)
public function rules()
{
    return [
        'hoge' => 'required|max:140'
    ];
}

バリデーションのルールについてより詳細は以下の公式ドキュメントを参照.
https://laravel.com/docs/9.x/validation#available-validation-rules

バリデーション対象に設定する要素の指定は Blade テンプレートで name="hoge" とした要素がチェック対象となる.

また, Laravel では CSRF(クロスサイトリクエストフォージェリ)対策のため, form の場合 Blade テンプレートに @csrf ディレクティブを付与する.

<form action="{{ route('hoge.create') }}" method="post">
    @csrf
    <textarea id="hoge-content" type="text" name="hoge"></textarea>
    <button type="submit">確定</button>
</form>

Route に名前をつける

Route に名前をつけることでコントローラや Blade テンプレートからパスではなく名前でアクセスできるようになる.

Route::post('/hoge/create', \App\Http\Controllers\Hoge\CreateController::class)->name('hoge.create');

作成した名前は以下のように Blade テンプレートなどからアクセスできる.

<form action="{{ route('hoge.create') }}" method="post">
    @csrf
    <textarea id="hoge-content" type="text" name="hoge"></textarea>
    <button type="submit">確定</button>
</form>

コントローラからアクセスする場合は以下.

    public function __invoke(CreateRequest $request)
    {
        //
        $hoge = new Hoge;
        $hoge->content = $request->hoge();    // データをモデルのメンバに設定
        $hoge->save();                        // DB のテーブルを更新
        return redirect()->route('hoge.index');    // hoge.index にリダイレクト. コントローラでも名前でアクセスができる
    }

エラーメッセージの実装

以下の @error ディレクティブを設定する.
バリデーションエラーがあった場合 {{ $message }} にエラーメッセージが表示される.

<textarea id="hoge-content" type="text" name="hoge"></textarea>
@error('hoge')
<p style="color: red;">{{ $message }}</p>
@enderror

複数項目のバリデーションをまとめる場合は @error に複数の名前を入れる.

@error('hoge', 'fuga')

エラーメッセージを日本語に変更

config/app.php を以下の通り変更

'locale' => 'ja',

... 省略

'fallback_locale' => 'ja',

lang ディレクトリの en ディレクトリをコピーして ja とリネームする.

ja ディレクトリ内の validation.php を日本語向けに編集する.

翻訳済みのバリデーションメッセージを利用する

自分で validation.php ファイルを翻訳するのは大変なので, OSS の翻訳済みバリデーションファイルを流用することも可能.

以下のコマンドでパッケージを入手する

$ sail composer require laravel-lang/lang:~10.3

インストールした ja ディレクトリを lang/ja にコピーする

$ cp -R vendor/laravel-lang/langlocales/ja lang/

これでバリデーションメッセージが日本語化されるが, name が 英語のままとなる.
lang/ja/validation.php の末尾に attributes を定義し name と表示名の対応を追加する.

...省略

    'attributes' => [
        'hoge' => 'ほげ',
    ],
];

画面からデータを取得し DB に保存

以上の実装を踏まえ実際に画面からユーザーが入力した情報を取得し DB に保存する流れを説明する.

RequestForm クラスに取得用メソッドを追加.
form の入力内容は $this->input() で取得できる.

public function hoge(): string
{
    return $this->input('hoge');
}

POST 用のコントローラにデータの取得と DB のテーブル更新処理を追加する

use App\Models\Hoge;

...省略

    public function __invoke(CreateRequest $request)
    {
        //
        $hoge = new Hoge;
        $hoge->content = $request->hoge();    // データをモデルのメンバに設定
        $hoge->save();                        // DB のテーブルを更新
        return redirect()->route('hoge.index');    // hoge.index にリダイレクト. コントローラでも名前でアクセスができる
    }

Laravel : MySQL にテーブル作成

Laravel : MySQL にテーブル作成

Laravel の機能を使用し MySQL データベースにテーブルを作成する方法について.

環境

  • macOS Big Sur
    • 11.6.5
  • Docker
    • 20.10.12
  • Laravel
    • 9.21.5
  • PHP
    • 8.1.8
  • Composer
    • 2.3.10
  • MySQL
    • 8.0.29

参考

概要

本記事の概要

  • データベースの確認
  • テーブルの作成
  • シーディングの生成
  • ORマッパー Eloquent の使用
  • Factory の作成

データベースの確認

Sail 環境で使用する MySQL の確認.

以下のコマンドで MySQL にログイン.

$ sail mysql

ログイン後に以下のコマンドでデータベースの一覧を確認.

show databases;

Laravel プロジェクトと同名のデータベースがある. これがそのプロジェクトで使用するデータベースとなる.

以下のコマンドで MySQL からログアウト.

exit;

テーブルの生成

以下のコマンドでテーブル生成用のマイグレーションファイルを生成する.

$ sail artisan make:migration create_hoges_table

hoges がテーブル名になる模様.
テーブル名は Artisan の他機能との連携を考慮すると 複数形にしたほうが無難そう.

database/migrations/yyyy_mm_dd_xxxx_create_hoges_table.php が作成される.
up と down の2つのメソッドが定義されている。up は追加するテーブルや拡張するカラムを指定する. down は戻す際の処理を記述する.

マイグレーションコマンドを実行しテーブルを作成する.

$ sail artisan migrate

以上で, データベースに hoges テーブルが作成される.

シーディングの生成

シーディングとは開発用のデータを生成すること.
以下の Artisan コマンドを実行.

$ sail artisan make:seeder HogesSeeder

database/seeder ディレクトリに HogesSeeder クラスが作成される.
作成されたクラスの run メソッドに追加データを記述する. 以下は追加例.

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class HogesSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //
        DB::table('hoges')->insert([
            'hoge_content' => Str::random(100),
            'created_at' => now(),
            'updated_at' => now(),
        ]);
    }
}

DatabaseSeeder.php の run メソッドに作成したシーダーを追加.

    public function run()
    {
        // \App\Models\User::factory(10)->create();
        $this->call([HogesSeeder::class]);

Artisan コマンドでシーダーを実行

$ sail artisan db:seed

以上で, 対象のテーブルにデータが追加される.

個別でシーダーを実行する場合は以下

$ sail artisan db:seed --class=TweetsSeeder

ORマッパー Eloquent の使用

Laravel の ORマッパー である Eloquent を使用したモデルの作成.
以下のコマンドを実行.

$ sail artisan make:model Hoge

app/Models ディレクトリに Hoge クラスが作成される.
作成されたクラスはクラス名のスネークケースかつ複数形のテーブルと自動でマッピングされる.
これが hoges テーブルのモデルとなる.

モデル名: Hoge -> テーブル名: hoges

マニュアルでの設定

モデルをデフォルトの設定から変えたい場合は以下のようにモデルにメンバを定義することにより変更可能.

モデルがマッピング命名規則に従っていない場合は以下のメンバ定義で紐付け

protected $table = 'hoge_table';    // 紐付けるテーブル名

id 以外の id の場合

protected $primaryKey = 'hoge_id';

主キーが増分整数ではない場合

public $incrementing = false;

主キーが整数でない場合

protected $keyType = 'string';

Factory の作成

Factory とは開発用に使用するダミーデータをシーダーに与える機能.

以下のコマンドを実行

$ sail artisan make:factory HogeFactory --model=Hoge

database/factories ディレクトリに HogeFactory ファイルが作成される.

生成した Factory クラスの definition メソッド、return 内に生成したいデータを記述する.

$this->faker を使用すればランダムでダミーのテキストを生成してくれる.

class HogeFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition()
    {
        return [
            //
            'content' => $this->faker->realText(100)
        ];
    }
}

デフォルトでは英語で生成されるため日本語にしたい場合は config/app.phpfaker_localeja_JP に変更する.

'faker_locale' => 'ja_JP'

Factory を使用してシーディングをする

database/seeders/HogesSeeder.php の run メソッドに対象のモデルの factory() メソッドを使用して作成する.
以下例

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\Hoge;

class HogesSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //
        Hoge::factory()->count(10)->create();
    }
}

Artisan でシードを作成する

$ sail artisan db:seed

シードが生成されていることを MySQL で確認する.

Laravel : リクエストを受け取り HTML を表示

Laravel : リクエストを受け取り HTML を表示

クライアントから GET リクエストを受け取り HTML を返す一連の流れの構築方法について記載.

環境

  • macOS Big Sur
    • 11.6.5
  • Docker
    • 20.10.12
  • Laravel
    • 9.21.5
  • PHP
    • 8.1.8
  • Composer
    • 2.3.10
  • MySQL
    • 8.0.29

参考

概要

Laravel での実装方法の大まかな流れは以下となる.

  1. コントローラを作成する
  2. HTML のテンプレートを作成する
  3. 作成したコントローラに HTML 表示の実装を追加する
  4. ルータに作成したコントローラへのルーティングを追加する

コントローラを作成する

Artisan で自動作成.

$ sail artisan make:controller HogeDir/HogeController

上記で app/Http/Controllers/HogeDir/HogeController.php が作成される.

ひとつのコントローラにひとつのエンドポイントの制約を課したい場合は以下のコマンド.

$ sail artisan make:controller HogeController --invokable

自動生成されたコントローラには __invoke メソッドが定義され, このメソッドにしかリクエスト処理ができないよう制約を付与できる.

HTML のテンプレートを作成する

Blade という動的に HTML を作成するテンプレートを使用する.

resources/views/hoge/index.blade.php を作成する.
Blade は {{ $hoge }} の記述で動的に値を設定できる.

<!doctype html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0,
          maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>アプリタイトル</title>
</head>

<body>
    <h1>アプリボディ</h1>
    <p>{{ $hoge }}</p>
</body>

</html>

作成したコントローラに HTML 表示の実装を追加する

先程作成した HogeController.php に表示用のメソッドを追加する.
シングルアクションコントローラの場合は __invoke メソッドに実装する.

作成したメソッド内で view をコールし HTML を返す.
第一引数は表示する HTML テンプレートでドット区切りでフォルダ階層を表す.
以下の場合は hoge フォルダの index.blade.php を指定.

第二引数は動的に表示する変数({{ $hoge }})の変数名と値.

通常のコントローラ場合

// メソッド名は任意
public function show()
{
    // 変数 hoge に laravel という文字列を設定
    return view('hoge.index', ['hoge' => 'laravel']);
}

シングルアクションコントローラの場合

public function __invoke(Request $request)
{
    // 変数 hoge に laravel という文字列を設定
    return view('hoge.index', ['hoge' => 'laravel']);
}

ルータに作成したコントローラへのルーティングを追加する

ルータ(routes/web.php)にルーティングを追加する.

  • 通常コントローラ
    • Route::get('/hoge', [\App\Http\Controllers\HogeController::class, 'show']);
    • hoge は アクセスされる URL のパス
    • HogeController は作成したコントローラ
    • show はアクセスするメソッド
  • シングルアクションコントローラ
    • Route::get('/hoge', \App\Http\Controllers\HogeController::class);
    • シングルアクションコントローラの場合メソッドの指定は不要

おわり

sail up -d でサーバを立ち上げた状態でブラウザから http://localhost/hoge にアクセスすると作成した HTML にアクセスできる.
ルーティングのイメージは大まかに以下の感じ.

Laravel ルーティング