【図解】RESTful WebサービスにおけるHTTPステータスコード

REST

RESTful WebサービスにおけるHTTPステータスコードに関して、アイコン認証Webサービスを構築するにあたって作成したダイアグラムを晒してみます

RESTful WebサービスではHTTPステータスコード=処理結果

弊社 アイコン認証Webサービス は、REST方式のWebサービスとして実装されています。

REST方式でない通常のWebアプリケーションでは、通常HTTPステータスコードとしては200(OK)しか返されません。
エラー等の状態を表す場合でもHTTPステータスは200(OK)が返され、画面に表示される内容にエラーを表すメッセージ等を含ませる事によって状態を表現します。

RESTfulなWebサービスを実現する場合には、処理結果はHTTPステータスコードで表現するべきとされています。

理由としては、以下のものがあげられます。

  • 適切なHTTPステータスコードを返さない ( 全部 200 (OK) とかの ) 場合、エンティティの中身を解析しなければ、処理結果が判別できない。
  • Web標準に従う事で、HTTPステータスコードから処理結果がどうだったのか理解できる。(少なくとも理解しやすい)

HTTPステータスコードだけで、処理結果の詳細 ( エラー内容等 ) を表現できないという意見も出そうですが、これら詳細情報はエラーが発生した場合のエンティティに詳細情報を含ませる事で解決できます。
(アイコン認証Webサービスでもエラー発生時には、エラー情報を表すXMLをエンティティのボディ格納してレスポンスを返すようにしています)

まず、HTTPステータスコードで判定し、ステータスコードに応じてその後の処理を振り分ける方が明らかに効率的ですし、Webサービスのような他システムから利用されるサービスにおいては適切な実装方法と言えるでしょう。

HTTPステータスコードを使うのは判ったけど、、、

RESTful なWebサービスを構築する場合に、処理結果に応じてHTTPステータスコードを使い分けるのは分かったけど、どういった場合にどういったコードを使えばいいのかは判らない。
普通にRESTfulでないWebアプリケーションを作っている/使っている限りにおいてはHTTPステータスコードなんか理解してなくても何とかなる。というか、なっている人は多いのではないでしょうか。

私の場合も、実際 RESTful Webサービスでどういったステータスコードを用いるべきか については、書籍を読み、実際に自分がフレームワークを構築・実装して、ようやくある程度の理解に至ったと言えます。

RESTful Webサービスの構築に関しては2010年に初めて携わったのですが、昨年 ( 2013年 ) アイコン認証Webサービスを実装するにあたり、改めてHTTPステータスコードの整理を行いました。

このとき作成したステータスコードのダイアグラムがあるので、以下公開してみます。

ダイアグラム

拡大
アイコン認証WebサービスにおけるHTTPステータス-ダイアグラム
アイコン認証WebサービスにおけるHTTPステータス-ダイアグラム

アイコン認証WebサービスにおけるHTTPステータスコードは概ね上のダイアグラムのようになっています。
各HTTPメソッドがリソースに対するCRUD操作に対応しています。

HTTPメソッド CRUD操作
POST CREATE (リソースの新規作成)
PUT UPDATE (リソースの更新)
DELETE DELETE (リソースの削除)
GET READ (リソースの参照)

実際には上記に当てはまらないパターンも存在します。
POSTメソッドはアイコンを利用した認証処理を行う場合も利用されますが、この場合返されるHTTPステータスコードは成功時には201(CREATED)ではなく 200(OK) となり、認証失敗時には 401 (UNAUTHORIZED) が返されます。
ダイアグラムはリソースに対するCRUD操作を行う場合の例となります。
※上のダイアグラム中の「認証」はWebサービス自体が利用可能かどうかを判定するための認証処理。

アイコン認証Webサービスでは Javaにおける RESTful Webサービスのための API仕様である JSR 311(JAX-RS) のリファレンス実装 : Jersey を利用しています。

405、406、415、及び、400の一部を除いたエラーハンドリングは Jersey が行ってくれています ( エラーメッセージをエンティティボディに格納する部分等で独自に拡張 )。

Jerseyに任せられるチェックに関してはお任せして、HTTPメソッド毎の処理とその結果に応じたステータスコードを返す部分を個別に実装しています。

ステータスコード一覧

ダイアグラムに出てくるステータスコードとその意味は下表のようになります。

ステータスコード 意味
200 (OK) OK。リクエストが成功した。
201 (CREATED) 作成した。
POST メソッドによるリソース作成リクエストが成功した。
レスポンスヘッダにはLocation情報 ( 作成されたリソースのURI ) を含みます。
204 (NO CONTENT) 内容なし。
DELETE メソッドによるリソース削除リクエストが成功した。
400 (BAD REQUEST) リクエストが不正。
XML中に必要な要素が記述されていない、XMLの書式に問題がある等。
401 (UNAUTHORIZED) 認証が必要。
認証の情報が正しくない。
403 (FORBIDDEN) アクセスが禁止されている。
認証は問題ないが、アクセス権がない。ユーザーアカウントで管理者アカウント権限が必要な操作を行った等。
404 (NOT FOUND) リソースが見つからない。
指定したURI にリソースが無い。
405 (METHOD NOT ALLOWED) 許可されていないメソッド。
POSTが許可されていないURIに対してPOST メソッドを利用した場合等。
406 (NOT ACCEPTABLE) 受理できない。
Acceptヘッダにサーバが送信可能なメディアタイプが指定されていなかった等。
409 (CONFLICT) リクエストは現在のリソースと競合するので完了できない。
作成、あるいは、更新しようとしたデータが、一意性制約等の理由で既存のデータと競合した。
415 (UNSUPPORTED MEDIA TYPE) 指定されたメディアタイプがサポートされていない。
PUT, POST リクエストのボディのメディアタイプがXMLでない場合等。
500 (INTERNAL SERVER ERROR) サーバ内部エラー。
処理中に例外が発生した。

ここで出てくるステータスコード以外のものもありますが、私がWebサービスを作成、利用している中で遭遇するものはだいたいこんなもんじゃないかという気がします。

メインフレーム系のエラーコードがかっちり定義されたシステムに携わった方等からすると、こんなんじゃ不十分と思われるかもしれませんが、BtoCのWebアプリケーション等では、エラーが発生する箇所といえば、以下のような感じではないでしょうか。

処理 対応するステータスコード
認証 ログイン画面 401 (UNAUTHORIZED)
権限チェック 管理画面など 403 (FORBIDDEN)
バリデーション 入力データのチェック 400 (BAD REQUEST)
データ登録/更新 ユーザIDの重複チェック等 409 (CONFLICT)
全般 例外的なシステムエラー
「管理者に連絡してください」的なメッセージが表示されるエラーの類
500(INTERNAL SERVER ERROR)

HTTPステータスに適切にマッピングを行い、詳細情報はエンティティボディに含めてレスポンスを返す事で、十分対応可能なのではないかと思われます。

まとめ

RESTful Webサービスを利用する上では、以下の原則を守る。

  • 適切なHTTPステータスコードを利用する。
    エンティティボディを解析して結果を判断するような事は避ける。
    より適切なエラーコードが存在するのに 500 (Internal Server Error) を返すような事はするべきではない。
  • 詳細なエラー情報等が必要な場合、HTTPレスポンスのエンティティボディに含める。

※もちろんHTTPステータスコード以外にも、処理内容に応じた適切なHTTPメソッドを用いるといった他の原則も守りましょう。