Webアプリの往復

INPUT · スライド

データをもらう往復

01 / 12

データの往復を、1回ぶん分解する

1本目で、Webアプリは入れ物の往復データの往復の2種類でできていると話したね。この章の最後では、そのうちデータの往復を1回だけ取り出して、中で何が起きているかを追いかけるよ。

見る場所は3つに分ける。

  • 送る側 … 何を送るのか
  • サーバの中 … 受け取ってから返すまでに、何が順に起きるのか
  • 返ってきたあと … 番号をどう読み、画面をどう描くのか

この3つに分けておくと、うまくいかないときにどこの話なのかがすぐ決まるよ。送った中身が悪いのか、サーバの中で落ちたのか、返ってきたものの扱いが悪いのか。同じ「データが出ない」でも、直す場所はまるで違うんだ。

02 / 12

送る側 ― 要求は4つの部品でできている

要求(リクエスト)は、いつも同じ4つの部品でできているよ。

  • 送り先(パス)… どこに向けての話なのか。/api/posts のような文字列
  • メソッド … その相手に何をしたいかGETPOST など
  • ヘッダ … 付随情報。身分証、中身の形式、受け取りたい形式など
  • ボディ … 送りつける中身そのもの。取ってくるだけの要求では空のことが多い

住所(パス)と、用件(メソッド)と、送り状(ヘッダ)と、荷物(ボディ)だと思うと近いよ。

大事なのは、同じパスでもメソッドが違えば別の要求だということ。/api/postsGET なら「一覧をくれ」、POST なら「1件足してくれ」という意味になるんだ。だから往復を指すときは、パスだけでなくメソッドとセットで言うようにしよう。

POST /api/postsContent-Type: application/json{ "title": "はじめまして" }

03 / 12

メソッドは「何をしたいか」の宣言

よく使うメソッドは5つ覚えておけば足りるよ。

  • GET … 取ってくる。サーバ側の状態を変えない
  • POST … 送りつける。新しく作るときによく使う
  • PUT … まるごと置き換えて書き換える
  • PATCH … 一部だけ書き換える
  • DELETE … 消す

ここでいちばん大事なのは、GET で状態を変えてはいけないということ。理由は2つあるよ。

ひとつは、もう一度開いただけで実行されてしまうこと。GET は履歴から戻ったり、ブラウザに先読みされたり、検索の巡回に踏まれたりする。「開いただけで消えた」が起きてしまうんだ。

もうひとつは、途中で保存(キャッシュ)されること。GET は何度出しても同じ結果が返る前提なので、あちこちで覚えられてしまう。状態を変える処理をそこに置くと、実行されたりされなかったりするよ。

GET    取ってくるPOST   送りつけるPUT    まるごと書き換えPATCH  一部だけ書き換えDELETE 消す

04 / 12

JSON ― 見た目を持たないデータの書き方

データの往復でよく使われる書き方が JSON だよ。運ぶのは値だけで、色も大きさも入っていない。

  • キーと値: で組にして、, で並べる
  • 値には数値・文字列・真偽・配列・入れ子の組を置ける
  • 文字列は必ず二重引用符で囲む(' は使えない)

どの形式で送ったかは、ヘッダの Content-Type で伝えるよ。中身を見れば分かりそうなものだけど、受け取る側が読み方を先に決められるように、外側に書いておくんだ。

見た目を持たないおかげで、同じ応答から Web の画面もスマホアプリの画面も作れる。並べ方を決めるのは受け取った側だね。

{  "id": 12,  "name": "さとう",  "tags": ["Web", "入門"],  "active": true}

05 / 12

サーバの中 ― 順番そのものが要点

要求が届いてから応答を返すまで、サーバの中ではだいたいこの順に進むよ。

  • ① ルーティング … このパスとメソッドを、どの処理に渡すか決める
  • ② 認証 … 誰からの要求かを確かめる(身分証を見る)
  • ③ 認可 … その人に、その操作が許されているかを判断する
  • ④ 検証 … 送られた中身が妥当か見る(数量が1以上か、など)
  • ⑤ 業務の処理 … 実際にやりたいことをする
  • ⑥ データベース・外部サービス … 読み書きしたり、外に聞きに行ったりする
  • ⑦ 返す形に整える … 返すデータと番号を組み立てる

覚えてほしいのは並びのほうだよ。確かめる前に、業務の処理をしない。誰か分からないうちに書き込んだり、中身が妥当か見る前にデータベースを触ったりしない、ということだね。

②と③は別ものだよ。②は「あなたは誰か」、③は「その人にそれが許されるか」。順番も②が先だ。誰か分からないうちに、許すかどうかは決められないからね。

① どの処理へ  ルーティング② 誰から      認証③ 許されるか  認可④ 中身は妥当  検証⑤ 業務の処理⑥ DB・外部⑦ 返す形へ

06 / 12

外部サービスは、サーバから呼ぶ

天気や地図や決済のような外部サービスを使うとき、呼びに行くのはブラウザではなくサーバだよ。

理由は1本目でやったとおり。ブラウザに送ったものは全部見えるので、秘密の鍵を端末に渡したら、それは公開したのと同じことになってしまう。

だから往復は2段になるよ。ブラウザは鍵を持たずに自分のサーバを呼ぶ。自分のサーバが鍵を付けて外部サービスを呼ぶ。返ってきたものから必要なぶんだけを選んで、ブラウザに渡すんだ。

おまけの利点もあるよ。外部サービスの都合(呼べる回数の上限、返る形の変更)を自分のサーバの中に閉じこめられるんだ。相手の仕様が変わっても、直すのは1か所で済むね。

ブラウザ  ↓ 鍵は無い自分のサーバ  ↓ 鍵を付ける外部サービス

07 / 12

返ってくる番号 ― 直す人が分かれる

応答には必ず3桁の番号(ステータスコード)が付いてくるよ。百の位で大きく分かれるんだ。

  • 2xx … 成功した
  • 3xx … 別の場所へ行ってほしい
  • 4xx頼み方の問題(要求の側に直すところがある)
  • 5xxサーバ側の問題(受けた側で処理が落ちた)

4xx のよく出るものだけ見ておこう。

  • 400 … 送られた中身がおかしい
  • 401誰からの要求か分からない(身分証が無い・切れている)
  • 403誰かは分かるが、その操作が許されていない
  • 404 … その宛先が無い

401403 の違いは、②認証で止まったか、③認可で止まったかだよ。401 は身分証を出せば通る見込みがあるけれど、403 は身分証を出し直しても通らない。

実務でいちばん効くのは、4xx5xx で直す人が違うこと。4xx は要求を出した側が送る内容を直す話、5xx はサーバを作った側が中を直す話だね。

2xx 成功3xx 別の場所へ4xx 頼み方の問題5xx サーバ側の問題

08 / 12

成功しても、中身が空のことがある

ここでよく取りちがえるのが、「失敗」と「0件」は別ものだということ。

一覧を取る要求に 200 が返って、中身が空の配列だった。これは成功だよ。サーバはちゃんと探しに行って、「該当するものはありませんでした」と正しく答えている。

  • 失敗 … 番号が 4xx5xx答えが出せなかった
  • 0件 … 番号は 2xx答えは出たが、該当が無かった

この2つを画面で同じ扱いにすると、「まだ投稿がありません」と出すべきところに「通信に失敗しました」と出てしまう。使う人には壊れているように見えるよね。

判断の順番は、まず番号、次に中身。番号で成功と分かってから、中身が空かどうかを見るんだ。

09 / 12

返ってきたあと ― 画面が取りうる4つの状態

往復の結果を画面にするとき、描き分けるべき状態は4つあるよ。

  • 読み込み中 … まだ返ってきていない
  • 成功して中身がある … 一覧や詳細を出す
  • 成功したが0件 … 「まだありません」と伝える
  • 失敗 … 何が起きたかと、次にどうすればよいかを出す

この4つを全部描かないと、動かない画面に見えるんだ。読み込み中を描かなければ、返ってくるまで真っ白のまま。0件を描かなければ、空白が置き去りになる。失敗を描かなければ、いつまでも読み込み中のまま止まって見えるよ。

作るときは、読み込み中と失敗を先に書くのがおすすめ。うまくいった場合だけ先に書いて、あとから足そうとすると、たいてい忘れられるからね。

読み込み中成功・中身あり成功・0件失敗

10 / 12

CORS ― 止めているのはブラウザ

別のドメインへデータの往復を出すと、ブラウザが応答を渡してくれないことがあるよ。これが CORS と呼ばれる仕組みだね。

最初に押さえてほしいのは、これはブラウザ側の安全装置だということ。サーバが弱いわけでも、攻撃されたわけでもないよ。

守っているのは、あなたが開いている別のサイトの権限を勝手に使われないようにすること。ブラウザは身分証を自動で付けて送ることがあるので、どこのページからでも自由に往復できると困るんだ。

だから、許可を出すのはサーバ側になるよ。応答のヘッダに「このドメインからなら渡してよい」と書いておくと、ブラウザが受け取りを許す。ブラウザ側の JavaScript で解除することはできないんだ。

そして、サーバ同士の通信では起きないよ。この仕組みを働かせているのはブラウザなので、ブラウザが関わらない往復には、止める側がいないからだね。

11 / 12

失敗したときに、何を見るか

データの往復が失敗したとき、たどる順番はいつも同じだよ。

まず番号を見る。 ここで探す場所が半分に決まるんだ。

  • 4xx送ったほうを見る。パス・メソッド・ヘッダ・ボディ。身分証を付け忘れていないか、中身の形は合っているか
  • 5xxサーバのほうを見る。送った中身をいくらいじっても直らないよ。サーバのログに、落ちた場所が残っている
  • 番号すら返らない … そもそも届いていない。宛先か、つながり方か、CORS の話だね

見る道具は、ブラウザの開発者ツールのネットワーク。ここで送ったものと返ってきたものの両方が見られるよ。片方だけ見て想像すると、たいてい外すんだ。

思いこみを捨てる近道は、送ったつもりのものが本当に送られているかを確かめること。付けたはずのヘッダが入っていない、というのはよくある話だよ。

12 / 12

まとめ

データの往復1回を、3つに分けて追ってきたね。

  • 送る側 … パス・メソッド・ヘッダ・ボディの4つ。GET は取ってくるだけで、状態を変えない
  • サーバの中 … ルーティング → 認証 → 認可 → 検証 → 業務の処理 → データベース → 返す形。確かめる前に処理をしない
  • 返ってきたあと4xx は頼み方の問題、5xx はサーバ側の問題で、直す人が違う401 は誰か分からない、403 は誰かは分かるが許されていない
  • 画面 … 読み込み中 / 中身あり / 0件 / 失敗の4つを描く。0件は失敗ではないよ

CORS はブラウザ側の安全装置で、許可を出すのはサーバ。サーバ同士の通信では起きないね。

この章はここまで。「どこの話をしているか」を決められるようになっていれば十分だよ。手を動かすときに、この地図の上へ道具の名前が乗っていくからね。