S3みたいなストレージサーバーっぽいものを自前で用意する①【ルーティング初期設定】

2022/03/13 2022/03/13 #S3 #ストレージサーバー

S3みたいなストレージサーバーっぽいものを自前で用意する

こんにちは。のんです。

実はちょっと前からのんラボのリプレースを考えていまして、ブログに載せる画像のアップロード先について考えていました。

これまではLaravelのデフォルト設定であるプロジェクト内のStorageディレクトリ内に保存していました。
ただ、リプレースする際にこれがかなりのネックになっていて、頭を抱えています。

新しいプロジェクトではキチンとストレージサーバーを用意してそこにアップロードするようにしようと思いました。

S3を検討していたのですが、S3使うだけじゃ何のインプットもアウトプットもできないので自前でストレージサーバーを用意しようと思い立ったのがこの記事を書くキッカケです。

今回からそのためのプロジェクトについて記事にしていきます。

一応、連載記事にしようと思っていますが、他にも書きたい内容(Rustとかチームビルディングとか)があるので、とびとびになるかも。

GitHubプロジェクトはこちら

できるだけフルスタックなフレームワークは使わない

  • Laravel
  • CakePHP
  • Symfony
  • Slim

などは利用しません。

しかし、自前で用意した生のPHPだけで書くという意味ではなく、laminasのコンポーネントや、leagueのコンポーネントを利用していきます。

ここでの狙いは、

PSR7やPSR15、RFC 7807やRFC 7807などの仕様、動作の勉強

となります。

何を組み合わせればいいのか。どのような実装になっているのか。

LaravelやCakePHPのドキュメントやAPIリファレンスを読んでいるだけでは得ることができない習慣を習得するため

です。

では、早速始めましょう。(今回は触りだけですが...)


まずはディレクトリ構成から

storage/backendが前提です。

.
├── app
│   ├── Adapter
│   ├── Domain
│   ├── Http
│   ├── Provider
│   └── Strategy
├── bin
├── tests
└── vendor

app/Adapter

主にRepository層の具象クラスをまとめる。

他のユースケース層で書きたくないものを逃がす場としても利用するかも。

ちょっと考え方ガバいけども、今の考え方で大丈夫そう。

app/Domain

主にUseCase層をまとめる。他にはEntities/ValueObjectをまとめます。つまり、レイヤードアーキテクチャでいうDomain層も含んでいるということ。

app/Http

主にHttpControllerをまとめる。MVCモデルのCです。

bin

独自コマンドを実行できるようにする予定。

リッチなMigration機能は求めていないので、単純なSQLを実行するためのコマンドや、定期的にファイルを調整するコマンドを用意するつもり。

と、だらだら書いたけども...

兎にも角にもRoutingとHttp Requestを捌きたい

自前のストレージサーバーと言ってもアップロード用のAPIを公開して受け付けるくらいの機能しかないです。この辺がFW(フレームワーク)を利用しない理由でもあります。

league/route

Route is a fast PSR-7 routing/dispatcher package including PSR-15 middleware implementation that enables you to build well designed performant web apps.

です。この仕様にあるライブラリを探すことになるのですが、このページで書いてある2つのライブラリを利用します。

laminas/laminas-diactoros

If you use Laminas Diactoros project you will also need

composer require laminas/laminas-httphandlerrunner

とあるので、

laminas-httphandlerrunner

も入れます。

これらを利用してテスト用のアクションを用意する

<?php
declare(strict_types=1);

include_once 'vendor/autoload.php';

/**
 * Load dotenv.
 */
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

/**
 * Load environment.
 */
$env = new Nonz250\Storage\App\Shared\ValueObject\Environment($_ENV['APP_ENV']);

/**
 * Create request.
 */
$request = Laminas\Diactoros\ServerRequestFactory::fromGlobals(
    $_SERVER,
    $_GET,
    $_POST,
    $_COOKIE,
    $_FILES,
);

/**
 * Setting router.
 */
$responseFactory = new Laminas\Diactoros\ResponseFactory();
$strategy = new League\Route\Strategy\JsonStrategy($responseFactory);
$router = new League\Route\Router();

if (Nonz250\Storage\App\Foundation\App::environment(Nonz250\Storage\App\Shared\ValueObject\Environment::LOCAL)) {
    $router
        ->group('test', static function (League\Route\RouteGroup $router) use ($strategy) {
            $router->get('/', static function (): array {
                return [
                    'message' => 'test',
                ];
            })->setStrategy($strategy);

            $router->get('/hello', static function (): Psr\Http\Message\ResponseInterface {
                $response = new Laminas\Diactoros\Response();
                $response->getBody()->write('<h1>Hello, World!</h1>');
                return $response;
            });

            $router->get('/action', Nonz250\Storage\App\Http\Test\TestAction::class);
        });
}

$response = $router->dispatch($request);

(new Laminas\HttpHandlerRunner\Emitter\SapiEmitter)->emit($response);

ブラウザでアクセスしてみます

スクリーンショット 2022-03-13 22.31.17.png

スクリーンショット 2022-03-13 22.31.29.png

スクリーンショット 2022-03-13 22.31.38.png

うまくいきました。

このルートはローカルのみ有効にしているので、本番では利用できません。

最後に

次回はPSR15を参照して、Middlewareを実装した内容を記事にします。

自分のためのAPIなので、認証が必要です。

Basic / Digestなどが一般的ですが、今回はDigest認証をAPI認証として利用します。

OAuth2の実装までやってみようと思いましたが、流石に時間かかりすぎるなと思ったのでやめました。

AuthMiddlewareについてはまた記事にしたいと思います。

そのときはよしなに。

.

のん

名刺 : About me.

YouTube : のんラボ

Twitter : @nonz250

Github : nonz250

Qiita : @nonz250

My Qiita posts My Qiita contributions My Qiita followers

主にPHPを使用し、サーバーサイドを担当。最近はフロントにも興味津々。

なにかを作ったりいじったりするのが好きで、個人開発なども行っている。

趣味はバイクアイコン画像は大抵愛車の「Z250」である。友達にアイコン描いてもらえて嬉しい。

PHP / Laravel / CakePHP2 / CakePHP3 / Vue / Nuxt / C# / etc...

Tags

#のんラボ #Laravel #Vue #個人開発 #ブログ #プログラミング #javascript #Html5 #WEBサービス #Twitter #今年の抱負メーカー #勉強方法 #PWA #モバイルアプリ #Android #ツーリング #バイクに乗るエンジニア #Z250 #秋吉台 #能登半島 #バイク #冒険 #東尋坊 #Squid #リバースプロキシ #hosts #axios #cropper #AdSense #Bootstrap #MySQL #高速化 #トドTask #Telescope #デバッグ #composer #テスト #セキュリティ #POSレジ #スマレジ #本部機能 #バリデーション #入力チェック #Mac #Chrome #テスト駆動開発 #開発手法 #UI #デザイン #WEBサイト #機能美 #PHP #Laravel 6 #コメント #バージョンアップ #vue-cli #localhost #BIツール #売上分析 #TANAX #MFK250 #ツアーシェルケース2 #RESTful #API #REST API #実務的 #PHP Tech Tutor #Smaregi Tech Talk #勉強会 # ブログ #CakePHP3 #CSRF #VSCode #開発環境 #CakePHP3.0 #さくらのレンタルサーバー #モジュールモード #シェル #メール #Gmail #relay #OGP #エラーページ #抱負 #家庭教師 #ドメイン駆動設計 #DDD #読書会 #那智の滝 #伊勢志摩 #伊勢志摩スカイライン #フロント #三方五湖 #レインボーライン #ボーイスカウト・ルール #プログラマが知るべき97のこと #リファクタリング #ユビキタス言語 #車輪の再発明 #マイクロサービス #デプロイ #QA #laravel-mix #Tips #storybook #@storybook/addon-actions #昇降デスク #コードレス #書斎 #オフィス #リモートワーク #働き方 #エラーハンドリング #スマレジ4 #pixel 5 #レビュー #スマレコ #TDD #RSS #404 #高山ダム #ラーツー #React #Nuxt #node_modules #エラー #インポート #設定方法 #環境構築 #Docker #フォレストパーク神野山 #学生向け #PR #採用 #Node.js #npm #しまなみ海道 #youtube #CSS #IE #SLA #Rust #千里浜なぎさドライブウェイ #千里浜 #インサイドセールス #曽爾高原 #無線LAN #ポートフォリオ #バルカンS #納車 #Next.js #チームビルディング #リーダー #悩み #Github Actions #Marp #ネタ #サーバー移行 #S3 #ストレージサーバー #RFC 7807 #Digest #認証 #Xdebug #CLI #西日本 #例外