軽量な機能のWeb APIを作成したい
Laravelのようなフルスタックではなく、軽量なフレームワークで簡単に構築したい
ということで、Slim4を使ってみたときのメモ書き
Step1.Slim4-skeleton環境の構築
git bashなどcomposeが使える環境を用意し、以下のコマンドを実行
Slim4-skeletonプロジェクト一式がダウンロードされる
composer create-project slim/slim-skeleton [任意のプロジェクト名]
補足.フォルダ構成について
最上位の親ディレクトリは、上記のコマンドで入力した「プロジェクト名」でフォルダが生成される
階層1 | 階層2 | 階層3 | 編集 | 概要 |
---|---|---|---|---|
app | dependencies.php | 〇 | ライブラリのコンテナ生成 Twingなどのライブラリをcomposeで追加後、依存関係の解決 |
|
settings.php | 〇 | 環境変数設定やライブラリの設定 | ||
middleware.php | 〇 | ライブラリを追加時、middlewareに依存関係を注入(Twingなどは必要) | ||
repositories.php | 〇 | 自分が作成したApplicationの依存関係の解決 | ||
routes.php | 〇 | URL振り分け、public/index.phpから遷移してくる | ||
logs | × | Slimログの出力先 | ||
public | 〇 | Slim4の公開ディレクトリ index.phpやcss/JavaScriptを格納 |
||
src | Application | Actions | 〇 | MVCの"VC"相当 ・routes.phpから受け取ったデータの振り分け ・後述Domainとのやり取り ・Responseのレンダリング |
Handlers | × | 基本編集は不要 | ||
Middleware | × | 同上 | ||
ResponseEmitter | × | 同上 | ||
Settings | × | 同上 | ||
Domain | DomainException | 〇 | MVCの"M"相当 ・データ構造クラスの定義、I/Fの定義 ・ビジネスロジックも表現 |
|
Infrastructure | 〇 | MVCの"M"相当 ・Model のデータ永続化を抽象化したオブジェクト ・データ取得(外部API,DB接続)として利用するなどでもよい |
||
var | × | Slim4のキャッシュファイルフォルダ コード反映が表示が更新されない場合、このフォルダ配下のキャッシュファイルを削除すると解決 |
||
vendor | × | Slim4本体ソースや追加したライブラリのソース格納先 |
Step2.ログ出力設定
Monologの設定を行いログ出力を設定/カスタマイズする
public/index.php
use DI\ContainerBuilder;
use Psr\Log\LoggerInterface; // ★追加
use Slim\Factory\AppFactory;
use Slim\Factory\ServerRequestCreatorFactory;
:(中略)
// Create Error Handler
$responseFactory = $app->getResponseFactory();
//$errorHandler = new HttpErrorHandler($callableResolver, $responseFactory); // ★コメントアウト
$logger = $container->get(LoggerInterface::class); // ★追加
$errorHandler = new HttpErrorHandler($callableResolver, $responseFactory, $logger); // ★追加
app/settings.php
// Global Settings Object
$containerBuilder->addDefinitions([
SettingsInterface::class => function () {
return new Settings([
'displayErrorDetails' => true,//★本番運用時falseにする。エラー詳細が画面に表示される
'logError' => true,//★変更
'logErrorDetails' => true,//★変更
'logger' => [
'name' => 'slim-app',
'path' => isset($_ENV['docker']) ? 'php://stdout' : __DIR__ . '/../logs/app.log',
'level' => Logger::DEBUG,
],
プロジェクト内で存在しないURLなどアクセスを行い、HTTP404などのエラーを起こすと、logs/app.logが生成される
ログのフォーマットを変更したい場合は、以下のような編集を行う
app/dependencies.php
use Monolog\Processor\UidProcessor;
use Monolog\Formatter\LineFormatter; // ★追加 ログフォーマット変更
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
:(中略)
return function (ContainerBuilder $containerBuilder) {
$containerBuilder->addDefinitions([
LoggerInterface::class => function (ContainerInterface $c) {
$settings = $c->get(SettingsInterface::class);
$loggerSettings = $settings->get('logger');
$logger = new Logger($loggerSettings['name']);
$processor = new UidProcessor();
$logger->pushProcessor($processor);
$handler = new StreamHandler($loggerSettings['path'], $loggerSettings['level']);
// ★フォーマット変更
// 形式例)日時、アクセス元IP、ログレベル、ログメッセージ
$date_format = 'Y-n-d H:i:s.u';
$userId = $_SERVER['REMOTE_ADDR'];
$format = "%datetime%,{$userId},%level_name%,%message%" . PHP_EOL;
$formatter = new LineFormatter($format, $date_format, true);
$handler->setFormatter($formatter);
$logger->pushHandler($handler);
return $logger;
},
Step3.WebサーバのDocumentRootにアップロードする
PHPが動作するWebサーバのDocumentRootにアップロードを行う
XAMPPなどのローカル環境で確認する場合、index.phpに以下の編集を行いパスを通す
public/index.php
// プロジェクト ベースURL ★追加
$app->setBasePath(getBasePath());
// Run App & Emit Response
$response = $app->handle($request);
$responseEmitter = new ResponseEmitter();
$responseEmitter->emit($response);
// Get Base Path ★追加
function getBasePath() {
$basePath = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME']));
if ($basePath == '/') return '';
return $basePath;
}
Step4.サンプルコードの動作確認を行う
上記のサンプルコードにアクセスを行い、それぞれ結果が表示されれば基本環境が構築できている
例1)http://localhost/[プロジェクト名]/public
例2)http://localhost/[プロジェクト名]/public/users
例3)http://localhost/[プロジェクト名]/public/users/1