やること
全16回「写真共有アプリを作ろう」の学習記録第2回です。
Qiita経由で見つけた下記URLを参考に手を動かします。
Vue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう (2 アプリケーションの設計
ツールのバージョン
Node | npm | Vue.js | Vue Router | Vuex | PHP | Laravel |
---|---|---|---|---|---|---|
10.7.0 | 6.4.1 | 2.5.21 | 3.0.2 | 3.0.1 | 7.2.10 | 5.7.19 |
目的
「0からアプリを完成させる流れ(アプリケーションの設計)」を経験して知見を獲得し、
その後のオリジナルアプリ作成
に生かすこと(2019/01/16に設定)
写真共有アプリ完成までの流れ(全16回)
- イントロダクション【済(1/16)】
- アプリケーションの設計 ←今ここ(1/17~1/21)
- SPA開発環境とVueRouter
- 認証API
- 認証ページ
- 認証機能とVuex
- 認証機能とVuex Part.2
- エラーハンドリング
- 写真投稿API
- 写真投稿フォーム
- 写真一覧取得API
- 写真一覧ページ
- 写真詳細ページ
- コメント投稿機能
- いいね機能
- エラーハンドリング
今回やったこと
SPAのアーキテクチャ
通信パターンの特徴
- 「普通の」Webアプリケーション
- ①ブラウザが画面要求(GET)またはデータ送信(POST)に対してさーばはHTMLを返却
- ②ブラウザはそのHTMLを描写して画面を構築する。ここまででワンセット。
- 上記の動きを繰り返すのが通常のWebページ
- SPA(Single Page Application)
- ① ブラウザは最初画面要求、サーバはHTMLを返却、ブラウザはそのHTMLを描写して画面を構築
- ② その後、ブラウザからAjaxでデータの要求/送信が行われ、サーバからJSONデータが返却される、ブラウザは受け取ったJSONデータを使用しJavaScriptによって画面の一部を書き換える
- ③ つまり、SPAは本来的な意味での「画面繊維」は発生しないのである
#実装する機能一覧
データベースとURLを設計するために、写真共有アプリの機能を洗い出します。
* 写真の一覧を表示する
* 写真を投稿する(会員のみ)
* 写真にいいねを付ける(会員のみ)
* 写真からいいねを外す(会員のみ)
* 写真からコメントを追加する(会員のみ)
* 写真に付けられたいいねの数を表示する
* 写真に付けられたコメントを表示する
* 会員登録する
* ログインする
* ログアウトする(会員のみ)
データベース設計
必要なテーブル
- photosテーブル
列名 | 型 | PRIMARY | UNIQUE | NOT NULL | FOREIGN |
---|---|---|---|---|---|
id | VARCHAR(255) | ★ | ★ | ★ | |
user_id | INTEGER | ★ | →users(id) | ||
filename | VARCHAR(255) | ★ | |||
created_at | TIMESTAMP | ||||
updated_at | TIMESTAMP |
- commentsテーブル
列名 | 型 | PRIMARY | UNIQUE | NOT NULL | FOREIGN |
---|---|---|---|---|---|
id | SERIAL | ★ | ★ | ★ | |
photo_id | VARCHAR(255) | ★ | →photos(id) | ||
user_id | INTEGER | ★ | →users(id) | ||
content | TEXT | ★ | |||
created_at | TIMESTAMP | ||||
updated_at | TIMESTAMP |
- likesテーブル
列名 | 型 | PRIMARY | UNIQUE | NOT NULL | FOREIGN |
---|---|---|---|---|---|
id | SERIAL | ★ | ★ | ★ | |
photo_id | VARCHAR(255) | ★ | →photos(id) | ||
user_id | INTEGER | ★ | →users(id) | ||
created_at | TIMESTAMP | ||||
udated_at | TIMESTAMP |
- usersテーブル(Laravelにデフォルトで用意されている)
列名 | 型 | PRIMARY | UNIQUE | NOT NULL | FOREIGN |
---|---|---|---|---|---|
id | SERIAL | ★ | ★ | ★ | |
name | VARCHAR(255) | ★ | |||
VARCHAR(255) | ★ | ★ | |||
password | VARCHAR(255) | ★ | |||
remember_token | VARCHAR(255) | ||||
email_verified_at | TIMESTAMP | ||||
created_at | TIMESTAMP | ||||
updated_at | TIMESTAMP |
ER図
※テキストで表現する方法を模索中
Web APIのURL設計
WebAPIとは?
Ajaxでデータ要求/送信を受け取ってJSONデータを返却するサーバサイドのプログラムをWebAPI(または単なるAPI)と呼びます。SPAの場合はこのWeb APIについてもURLを設計する必要があります。
普通のWebページ(マルチページアプリケーション)とWebAPIの違い
(使用できる)HTTPメソッドの種類が違う
- マルチページアプリケーション
- GET
- POSTの2種類
- WebAPI
- GET
- POST
- PUT
- PATCH
- DELETE
なぜ上記のような違いが出るのか?
マルチアプリケーションの場合
マルチページアプリケーションはサーバーへのリクエスト発行をアンカーリンク(
<a>
)とフォーム送信(<form>
)に頼っています。アンカーリンクはGETリクエストを発行しますし、フォーム要素のmethod
属性はGETとPOSTしかサポートしていません。
WebAPIの場合
WebAPIはAjaxによってリクエストを発行するので上記の制約はありません。HTTPの仕様として定義されているメソッドはすべて使用できるというわけです。具体的には以下の5種類のHTTPメソッドを使うことが出来ます.
メソッドの種類
メソッド | 意味 |
---|---|
GET | リソースの取得 |
GET | リソースの新規作成 |
PATCH | リソースの一部変更 |
PUT | リソースの置き換え |
DELETE | リソースの削除 |
「リソース」というのは少し抽象的な表現ですが、「ユーザー」「写真」「商品」「ツイート」などリクエストにより操作したい対象のデータを指します。
WebAPIのURL設計
- 使用できるHTTPメソッドの違いはURL設計にも影響します。WebAPIの場合は使えるHTTPメソッドをフル活用した設計の考え方をするのが一般的です。
URL設計の具体例
マルチアプリケーションの場合
具体例で考えてみましょう。あるアイテムの新規作成、編集、削除のURLを設計するとします。マルチアプリケーション流に考えると以下のようになるでしょう。
POST / items / create # 新規作成
POST / items / update # 編集
POST / items / dekete # 削除
データの処理を依頼するためのメソッドがPOSTしかないので、ざっくり画面を要求するだけの時はGET、それ以外のデータ処理を要求するときはPOSTとして、データ処理の要求内容はURLのパスで表現するという考え方です。
それに対して、WebAPIの場合
このケースをWebAPI流に考えると以下のようになります
POST /items # 新規作成
PATCH /items # 編集
DELETE / items # 削除
「itemをDELETEする」のように、URLが目的語でHTTPメソッドが動詞という形式になっています。データ処理の要求内容をHTTPメソッドで表現できるからこそ可能な設計ですね。
URL一覧
上記の説明を踏まえて、写真共有アプリで必要なWebAPIのURLは以下のとおりです。★マークがついているURLは認証済みでないとアクセスできません。
URL | メソッド | 認証 | 内容 |
---|---|---|---|
/api/photos | GET | 写真一覧取得 | |
/api/photos | POST | ★ | 写真投稿 |
/api/photos/{写真ID} | GET | 写真詳細取得 | |
/api/photos/{写真ID}/like | PUT | ★ | 写真 いいね追加 |
/api/photos/{写真ID}/like | DELETE | ★ | 写真 いいね解除 |
/api/photos/{写真ID}/comments | POST | ★ | 写真 コメント追加 |
/api/register | POST | 会員登録 | |
/api/login | POST | ログイン | |
/api/logout | POST | ★ | ログアウト |
/api/user | GET | 認証ユーザー取得 |
- 分かりやすいようにWebAPIの頭にはすべて
/api
を付けています。
* いいね数やコメント内容は写真一覧または詳細データに含みます。
* いいねの付け外しをPUT
とDELETE
で表現しました。外すのがDELETE
なのはいいとして付けるのがなぜPUT
かというと、まず同じ人間
が同じ写真にいいねを何個も付けることは現実的な仕様として考えにくいので新規作成を意味するPOST
は不自然だと思いました。またいいねはONかOFFの状態しかなく、一部だけ変更することはないのでPATCH
も不自然です。仮にいいねを付けるリクエストを同じ写真に繰り返し行っても、置き換えを表すPUT
であれば意味的に1個しかつかなそうな感じがするのでPUT
を採用しました。
- POSTがいいかPUTがいいかというような議論はあくまでURL設計を単体で見たときに分かりやすいか、美しいかを言ってるにすぎません。
- HTTPメソッドの選択などのURL設計とプログラムの実装内容は関係がないことに注意してください。
- 結局URLとそれに応答するプログラムはルート定義で恣意的に決めるのですから。
- 論理的に不自然なURLを選択したからといってプログラムが正しく動作するかは別問題です。
API以外
API以外にサーバサイドで用意する必要があるURLは以下のとおりです。
URL | メソッド | 認証 | 内容 |
---|---|---|---|
/ | GET | 最初にHTMLを返却する | |
/photos/{写真ID}/download | GET | 写真をダウンロード |
フロントエンド
さて、最後に画面側のURLも載せておきます。
こちらはフロントエンド(Vue Router)で実現します。
URL | 内容 |
---|---|
/ | 写真一覧ページ |
/photos/{写真ID} | 写真詳細ページ |
/login | ログイン・会員登録ページ |
おわり
今回はここまで
参考資料
Webを支える技術 -HTTP, URI, HTML,そしてREST
HTTPの教科書
次回やること
次の章からコードを書いていきます。
まずはSPAプロジェクトの作成からVue Routerの導入まで進みます。
Vue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう(3)SPA開発環境とVue Router