2013-03-24 9 views
9

RESTful APIでHTTPステータスコードを返すベストプラクティスは何ですか?私は私のPHPフレームワークにLaravel 4を使用しています。エラーの場合にRESTful APIでのエラーのベストプラクティス

、Iは

return Response::json('User Exists', 401); 

又は

を使用する必要がsuccess

return Response::json([ 
    'success' => false, 
    'data' => 'User Exists'], 
    401 
); 

又は

フラグの代わりに200を使用して含めますエラー

return Response::json([ 
    'success' => false, 
    'data' => 'User Exists'], 
    200 
); 

と成功の場合は、任意のデータを返す必要はありませんがある場合の4xxは、successに依存することを決定するために、あなたはまだ何も返していますか?

PHPのAPIコード

public function getCheckUniqueEmail() { 
    // Check if Email already exist in table 'users' 
    $uniqueEmail = checkIfEmailExists(); 

    // Return JSON Response 
    if($uniqueEmail) { 
     // Validation fail (user exists) 
     return Response::json('User Exists', 401); 
    } else { 
     // Validation success 
     // - Return anything? 
    } 
} 

答えて

12

あなたはlist of available HTTP status codesを見てみると、あなたはいくつかの点で、彼らは本当にそれ自体でエラーを説明することはできません、それらの多くがあることを認識しますが、単独で使用されます。

質問に答えるには、2つの部分があります。 1つは、APIがエラーの原因を伝える方法と、APIのユーザー(たいていの場合、別の開発者)が読むことができる有用な情報を追加する方法です。可能な限り多くの情報を追加する必要があります。

その他の部分:HTTPステータスコードは、特定のエラー(および成功)状態をどのように区別するのに役立ちますか?

この後半部分は実際には1つの事よりも難しいです。 404が「見つからない」と言うために使われるという明白なケースがあります。サーバー側のエラーは500です。

HTTP認証の資格情報が存在する場合、操作を正常に許可しない限り、ステータス401は使用しません。 401は、通常、悪いブラウザのダイアログボックスを起動します。

リソースが一意で既に存在する場合は、ステータス「409 Conflict」が適切と思われます。ユーザーの作成が成功すると、ステータス「201 Created」も良いアイデアのように聞こえます。

HTTPプロトコル(DAVなど)の拡張に関連するものや、完全に標準化されていないもの(ステータス「420 Enhance your calm」のようなもの)が、Twitter APIから提供されています。 http://en.wikipedia.org/wiki/List_of_HTTP_status_codesを見てこれまでに何が使用されているかを見て、エラーの場合に適切なものを使用するかどうかを決定してください。

私の経験から、ステータスコードを選択して使用するのは簡単ですが、一貫して既存の基準に従って行うのは難しいです。

他の人が文句を言うかもしれないので、私はここで止めません。 :) RESTfulなインターフェイスを正しく実行すること自体は難しい作業ですが、インターフェイスが多くなればなるほど、より多くのエクスペリエンスが集められます。

編集:バージョン管理について

example.com/api/v1/stuffそれは動作しますが、それは素晴らしいではありません:そうと同じように、URLにバージョンタグを置くために悪い習慣と考えられています。

しかし、最初のものは、次のとおりです。どのようにあなたのクライアントは、どのように彼は、JSONまたはXMLを取得するかを決めることができ、すなわち、彼は取得したい表現の種類を指定していますか?回答:Acceptヘッダーを使用してください。 JSONの場合はAccept: application/json、XMLの場合はAccept: application/xmlを送ることができます。彼は複数のタイプを受け入れることさえできます。そして、サーバが何を返すのかを決定するのです。

サーバーがリソース(JSONまたはXML、クライアント選択)の複数の表現と答えるように設計されていない限り、実際にクライアントのために多くの選択肢がありません。しかし、依然としてクライアントが少なくとも "application/json"を自分の唯一の選択肢として送信し、それに応答してヘッダContent-type: application/jsonを返すことは良いことです。このようにして、両側は、相手側がそのようなコンテンツを見ることを期待していることを明確にします。

バージョンが完成しました。 URLにバージョンを入れると、さまざまなリソース(v1とv2)が効果的に作成されますが、実際にはアクセスする方法が異なるリソース(= URL)が1つしかありません。新しいバージョンのAPIを作成するには、リクエストのパラメータやレスポンスの表現が現在のバージョンと互換性がない場合に、新しいバージョンのAPIを作成する必要があります。

JSONを使用するAPIを作成するときに、汎用JSONを処理しません。あなたは、あなたのAPIにとって何となくユニークな具体的なJSON構造を扱います。サーバーから送信されたContent-typeにこれを示す必要があります。 Content-type: application/vnd.IAMVENDOR.MYAPI+jsonは、基本的なデータ構造がapplication/jsonであることを世界に伝えますが、あなたの会社とあなたのAPIは、実際にどの構造を期待しているかを示しています。そしてそれは正確にAPI要求のバージョンがapplication/vnd.IAMVENDOR.MYAPI-v1+jsonに収まるところです。

URLにバージョンを入れるのではなく、クライアントがAccept: application/vnd.IAMVENDOR.MYAPI-v1+jsonヘッダーを送信し、Content-type: application/vnd.IAMVENDOR.MYAPI-v1+jsonで応答するとします。これは実際には最初のバージョンでは何も変わりませんが、バージョン2が登場したらどうなるかを見てみましょう。

URLのアプローチは完全に無関係な新しいリソースのセットを作成します。クライアントはexample.com/api/v2/stuffexample.com/api/v1/stuffと同じリソースであるかどうか疑問に思うでしょう。クライアントはv1 APIでいくつかのリソースを作成していて、この情報のURLを保存していた可能性があります。これらのリソースをすべてv2にアップグレードする方法を教えてください。リソースは実際には変更されておらず、同じですが、変更された唯一の点はv2で異なって見えることです。

はい、サーバーは、v2 URLへのリダイレクトを送信してクライアントに通知する場合があります。しかし、リダイレクトは、クライアントがAPIのクライアント部分をアップグレードする必要があることを通知しません。

バージョンで受け入れヘッダーを使用する場合、リソースのURLはすべてのバージョンで同じです。クライアントはバージョン1または2のいずれかでリソースを要求することにします。サーバーは親切で、バージョン1の要求ではまだバージョン1の要求に応答しますが、すべてのバージョン2の要求には新しく光沢のあるバージョン2の応答があります。

サーバーがバージョン1の要求に応答できない場合、サーバーはHTTPステータス「406 Not Acceptable」を送信してクライアントに通知できます(要求されたリソースは、送信されたAcceptヘッダーリクエスト。)

クライアントは両方のバージョンを含む受け入れヘッダーを送信することができます。これにより、サーバーは自分が一番好きなもの、つまりスマートクライアントがバージョン1と2を実装し、受け入れヘッダーと待機サーバーはバージョン1から2にアップグレードする必要があります。サーバーはバージョン1または2であるかどうかをすべての応答で通知し、クライアントはそれに応じて行動できます。サーバーバージョンのアップグレードの正確な日付を知る必要はありません。

要約:非常に基本的なAPIであっても、バージョンがあっても内部的な使い方が限定されていると、過剰な使用になる可能性があります。しかし、これが今から1年後になるかどうかは決して分かりません。 APIにバージョン番号を含めることは、常に非常に良い考えです。これは、APIが使用しようとしているMIMEタイプの中に最適です。既存の単一のバージョンを確認するのは簡単ですが、既存のクライアントを混乱させることなく、後で透過的にアップグレードすることができます。

+0

安らかなAPIは、自分のサイトのajax/backbonejs/jqueryを使用するためのものです。この場合、同じエラーコード(400など)に固執すべきですか?あるいは、AJAXの応答ごとに200を返し、エラーが発生したかどうかを確認するために 'success'変数をチェックしてください。 – Nyxynyx

+1

いいえ、エラーコードを介して基本的な"成功/エラー "の事実を示すことは非常に良い考えです。エラー応答はHTTPクライアントによって異なるように処理されます。キャッシュされてはいけません。データペイロード内で同じことを示すことも良いことです。私自身のAPIは、成功すれば「データ」を、失敗した場合は「エラー」を持ちます。これは基本的には「成功=真偽」と同じですが、それは私のために働きます。しかし、ステータス "400 Bad request"は、それがあなたが思う一般的なクライアントのエラーステータスではありません。そのようなことはありません。エラー状態を指定する必要があります。 – Sven

+2

すばらしい答え、Sven! しかし、あなたは言う:>バージョン管理について:私は同意しないURLにバージョン >タグを入れるのは悪い習慣と考えられます。 Apigeeの[guide](http://apigee.com/about/api-best-practices/restful-api-design-secondedition)にはバージョン番号を使用するのがベストプラクティスであると結論づけられていますURL。彼らはまた、返品ステータスコードを明らかにする。 – unicopter

2

私はすべてのステータスを200にしません。それはちょうど混乱するでしょう。

Jqueryを使用すると、異なる応答コードを別々に処理することができます。そのためのメソッドが既に組み込まれていますので、アプリで使用することができ、アプリが大きくなったときに他のユーザーが使用できるようにAPIを提供できます。

編集: はまた、私は非常にLaravelとAPIの開発については、この話を見てお勧めします。

http://kuzemchak.net/blog/entry/laracon-slides-and-video

+0

ビデオリンクは便利ですが、スピーカーはURLにバージョン番号を持つようなRESTful APIを実装しています。それは "Accept"ヘッダーのためのものです。 – Sven

+0

@Svenあなたはそれをどのように使用するかについてもっと詳しく説明できますか?私は好奇心です=) – msurguy

+0

私の答えを更新しました。 – Sven

1

Symfony\Component\HttpFoundation\Responseに及ぶIlluminate\Http\ResponseでHTTPステータスコードのいくつかのリストがあります。あなたはあなたのクラスでそれを使うことができます。例えば

use Illuminate\Http\Response as LaravelResponse; 
... 
return Response::json('User Exists', LaravelResponse::HTTP_CONFLICT); 

それははるかに読みやすいです。

関連する問題