簡単な仕様
GET api/files
ファイル情報の配列を取得する。GET api/files/{file}
指定したファイル情報を取得する。POST api/files
ファイルを登録する。PATCH api/files/{file}
指定したファイルを更新する。DELETE api/files/{file}
指定したファイルを削除する。
ファイル登録時などのレスポンスは、最初、 URL だけでいいや、 DB で管理したく無いし、と思っていました。 しかし、 How to show files already stored on server – FAQ · Wiki · Matias Meno / Dropzone · GitLab を読むと name, size, url が Dropzone.js では必要なようです。 なので、面倒ではありますが DB でこれらを管理しようと思います。。。 こうなると、例えば POST 時のレスポンスは次のようになるかと思います。
作っていく
ファイル生成や設定やコード数の少ない変更など
ファイルは DB ではなく一般公開するディレクトリへ保存する予定なため、 ファイルストレージ 6.x Laravel にしたがってシンボリックリンクを貼ります。
今回は常に一般公開しますので、デフォルトのファイルシステムを public へと変更します。
コントローラーを作りました。中身はあとで書いていきます。
ルーティングをしました。 APIリソースルート – コントローラ 6.x Laravel です。
モデルと、マイグレーションファイルを生成します。
また、レスポンスは API リソースファイルとした方が良さそうと感じましたので作っておきます。
そして、 POST 、 GET や PUT 時のレスポンスは data でラップされていない構造で受け取りたいので、 データラップ – Eloquent: APIリソース 6.x Laravel の通りに修正しました。
あと、テストとそのためのファクトリも作っておきます (ファクトリは結局使いませんでした) 。
POST api/files
ファイルを登録する。この部分を作るにあたって調べたこと
- ファイルアップロード – ファイルストレージ 6.x Laravel
- ファイルURL – ファイルストレージ 6.x Laravel
- ファイルアップロードのテスト – HTTPテスト 6.x Laravel
GET api/files/{file}
指定したファイル情報を取得する。この部分を作るにあたって調べたこと
- Illuminate\Http\Testing\File | Laravel API 。
getSize()
やstore()
を使った。 - 事前にファクトリクラスを用意したが、テストではフェイクファイルを作成してそれに依存するような形で DB レコードを用意する形となった。この状況ではファイルはテストが終われば自動的に消えるが、 DB レコードは基本的には消えない (インメモリ SQLite をデータベースとして指定しているため結果としては消えるけれども) 。ファクトリの中でフェイクファイルを生成しようかと思ったが、ファイルは消え、レコードは残る事態になりかねないため、ファクトリは使用しなかった。
GET api/files
ファイル情報の配列を取得する。この部分を作るにあたって調べたこと
ページネーションは無しとしました。サンプル程度のものである、ということと、実際に使う時は何かにファイルが数件紐づいている状態から扱うと考えられるためです。
PATCH api/files/{file}
指定したファイルを更新する。この部分を作るにあたって調べたこと
DELETE api/files/{file}
指定したファイルを削除する。この部分を作るにあたって調べたこと
REST API の DELETE メソッドの成功時のレスポンスは何を返せば良いのか、毎回悩みます。 結局、ステータスコードは 204 でレスポンスボディは何も無し、としました。
- 200 or 204 どっちを使うか – Qiita
- koel/SongController.php at master · koel/koel ← 様々な場面で参考にしている、音楽プレーヤーアプリのコード
完成したメイン部分のコード全体
ユニットテストと、コントローラーがメインです。ファクトリは結局使いませんでした。。。
app/Http/Controllers/Api/FileController.php
app/Http/Resources/File.php
app/Models/File.php
database/migrations/2021_05_04_222600_create_files_table.php
tests/Feature/FileControllerTest.php
。最初、 Storage::fake();
を createFile
メソッドに書いていました。けれども、テストメソッドの中で複数回 Storage::fake();
を実行すると、 2 回目の Storage::fake();
の前に生成したファイルが消えるという予想外な動きをしました。全てのテストメソッドでフェイクファイルを扱っていますので、 setup
で Storage::fake();
を実行するようにしました。
今にして思えば、createFile
メソッドを setup
メソッドで 2 回ほど実行しておいて、各テストメソッドでは事前に作成指定おいたフェイクファイルとそれに紐づくレコードを利用する、というようにすることで、各テストメソッドでの準備にあたるコードをもっと減らせたのではないかと思います。
おわりに
なぜこんなことをやっているかというと、 Vue.js 用の Dropzone ライブラリを軽く試したメモ – oki2a24 の続きで Dropzon.js の使い方を調べたく、そのために、ファイルをアップロードできるサーバを用意する必要があり、無いので、本投稿で作っているのでした。
ようやく用意できました。
ただ、 Dropzon.js を試しているうちに、本投稿で作ったものに手が入りそう、と思っています。
以上です。