岩本隆史の日記帳(アーカイブ)

はてなダイアリーのサービス終了をうけて移行したものです。更新はしません。

Webアプリにおける適切なレスポンスボディとは

HTTPの仕様からWebアプリのMVCを見直す」という記事を書きながら、Webアプリにおける適切なレスポンスボディとはどのようなものなのか、あらためて考える必要があると感じました。今回の記事はその実践です。

考えるべきケース

まず下記のようなケースは、答えが自明であり、考えるまでもないものです。

  • 要求されたリソースの表現を返せばよい場合(例:GETで「200 OK」)
  • レスポンスボディを返してはならない場合(例:「204 No Content」「304 Not Modified」)

そのように処理すればよいだけだからです。

考えるべきは、下記のようなケースです。

  • 正常に処理されたことを伝えたい場合(例:PUTで「200 OK」)
  • 他のリソースを参照させたい場合(例:「201 Created」「303 See Other」)
  • クライアントに入力値の修正をうながしたい場合(例:「400 Bad Request」)
  • エラー状況を伝えたい場合(例:「503 Service Unavailable」)

空のレスポンスボディは不親切

具体例として「303 See Other」について考えてみましょう。RFC 2616では下記のように規定されています。

異なる URI は、レスポンス内の Location フィールドによって与えられるべきである。リクエストメソッドが HEAD でなければ、レスポンスのエンティティは新しい URI へのハイパーリンクを持った短いハイパーテキストの注釈を含むべきである。

「ハイパーテキスト転送プロトコル -- HTTP/1.1」10.3.4 303 See Other

Locationヘッダさえ返せばレスポンスボディは空でOKというわけではなく、参照させたいURIへのリンクをレスポンスボディに含めるべきというわけです。もちろん「べき」なので、従うかどうかはWebアプリ製作者の判断次第ですが、クライアントによっては自動リダイレクト機構がOFFになっており、真っ白な画面が表示されるだけという結果も想定できるのであってみれば、空のレスポンスボディを返すのは不親切といえるでしょう。

メッセージとリンクを含めよ

詳細は省きますが、他のステータスコードRFC規定も考え合わせると、レスポンスボディに最低限含めるべきは下記のふたつではないかと思われます。

  • メッセージ
  • 関連リソースへのリンク(広義のリンク、すなわちフォームを含む)

ステータスコードはあくまでクライアントに対する符丁にすぎません。ユーザに的確な状況を知らせるには、人間に読めるメッセージが必要です。バリデーションエラーを想定してください。「400 Bad Request」を返したところで、「メールアドレスは必須です」のようなメッセージがなければ、ユーザは何を修正したらよいか分かりません。

また、関連リソースへのリンクが含まれないと、そこでユーザインタラクションが行き止まりになってしまいます。サーバエラーの場合でも、トップページやヘルプなど関連リソースへのリンクを提供する必要があるでしょう。

まとめると、Webアプリにおいて、リソース表現をそのまま返さないタイプのレスポンスボディには、メッセージとリンクを含めるべきだと私は考えているということです。

microformats で定義できないか

話を広げすぎるようですが、このメッセージやリンクを microformats で定義できれば、クライアント(特にAjaxクライアント)で扱いやすくなるのではないかと想像しています。下記のようなイメージです。

<div class="message">
<p>ブックマークが登録されました。</p>
</div>
<ul class="links">
<li><a href="/bookmarks/1.html" rel="created" type="application/xhtml+xml">ブックマーク(XHTML)</a></li>
<li><a href="/bookmarks/1.json" rel="created" type="application/json">ブックマーク(JSON)</a></li>
</ul>

リンクタイプ(上記例では「rel="created"」)はよく考える必要があるでしょうが、ともかく、「リソース表現をそのまま返さないタイプのレスポンスボディ」でも microformats が効果的に使えるのではないかと思っています。