APIからJSONレスポンスを構築するための標準やベストプラクティスはありますか?明らかにすべてのアプリケーションのデータは異なっているので、私はあまり関係ありませんが、そうであればむしろ「レスポンスの定型句」です。私の言っていることの一例:
リクエスト成功:
{
"success": true,
"payload": {
/* Application-specific data would go here. */
}
}
失敗した要求:
{
"success": false,
"payload": {
/* Application-specific data would go here. */
},
"error": {
"code": 123,
"message": "An error occurred!"
}
}
はい、いくつかの標準があります(標準の定義にはいくつかの自由がありますが)。
JSON APIの記述形式もあります。
成功応答の返信 data
{
"data": {
"id": 1001,
"name": "Wing"
}
}
エラーレスポンスリターン error
{
"error": {
"code": 404,
"message": "ID not found"
}
}
クライアントがJSの場合は、if ("error" in response) {}
を使用してエラーがないかどうかを確認できます。
私は事実上の標準が実際には出現していないと思います(そして決してそうはしないかもしれません)。それにもかかわらず、これが私の考えです。
リクエスト成功:
{
"status": "success",
"data": {
/* Application-specific data would go here. */
},
"message": null /* Or optional success message */
}
失敗した要求:
{
"status": "error",
"data": null, /* or optional error payload */
"message": "Error xyz has occurred"
}
長所:成功時とエラー時の両方で同じトップレベルの要素
デメリット:エラーコードはありませんが、必要に応じて、ステータスを(成功または失敗)コードに変更することも、または別の最上位項目「code」を追加することもできます。
あなたが疑問に思っているのがRESTウェブサービスのデザイン、そしてより正確には成功/エラーに関するものであるとしましょう。
3種類のデザインがあると思います。
エラーがあったかどうかを示すために のみHTTPステータスコード を使用してください(通常はそれで十分です)。
HTTP Status + json body を使用します(エラーであっても)。エラー(例:コード、メッセージ、理由、タイプなど)に対して統一された構造を定義し、それがエラーに使用された場合、それが成功した場合は予想されるJSON応答を返すだけです。
httpステータスを忘れる (例:常にステータス200)、常にjsonを使用し、応答のルートにブールのresponseValidとエラーオブジェクト(コード、メッセージなど)を追加します。それ以外の場合はエラー、他のフィールド(成功)は移入されます。
長所:クライアントは、JSONストリングである応答の本体のみを扱い、状況(?)を無視します。
短所:あまり標準的ではありません。
それを選ぶのはあなた次第です:)
APIに応じて、2または3を選択します(json rest apisには2を好みます)。 REST Apiの設計で私が経験したもう1つのことは、各リソース(url)のドキュメンテーションの重要性です。パラメーター、本体、応答、ヘッダーなどです。
また、jersey(jax-rs実装)+ genson (Java/jsonデータバインディングライブラリ)の使用をお勧めします。クラスパスにgenson + jerseyをドロップするだけで、jsonが自動的にサポートされます。
編集:
ソリューション2は実装が最も困難ですが、利点は、ビジネスエラーだけでなく例外をうまく処理できることです。初期の取り組みがより重要ですが、長期的には勝ちです。
解決策3は、サーバーサイドとクライアントの両方に実装するのは簡単ですが、responseValid +エラーも含むレスポンスオブジェクトに返すオブジェクトをカプセル化する必要があるので、それほどいい方法ではありません。
私はこれが標準であると主張するのは傲慢ではないので、私は「私が好む」形式を使用します。
私は簡潔な回答を好みます(/ articlesのリストを要求するときは、JSONの一連のarticleが必要です)。
私のデザインではステータスレポートにHTTPを使っています。 200 はペイロードだけを返します。
400 は、requestに問題があったことを示すメッセージを返します。
{"message" : "Missing parameter: 'param'"}
404 model/controler/URIが存在しない場合
私の側で処理にエラーがあった場合は、メッセージとともに 501 を返します。
{"message" : "Could not connect to data store."}
私が見たものから、かなりの数のREST風フレームワークがこれらの方針に沿っている傾向があります。
理論的根拠 :
JSONは payload の形式になっているはずです。セッションプロトコルではありません。冗長なセッション風ペイロードの全体的な考え方は、XML/SOAPの世界と、それらの肥大化したデザインを作成したさまざまな誤った選択からもたらされます。それがすべて大きな頭痛の種であることに気付いた後、REST/JSONの全体的なポイントはKISS it、そしてHTTPに従うことでした。どちらのJSendにもリモートに standard があるとは思いません。特に、それらの間に冗長性はありません。 AJAXにjQueryを使用する場合(ほとんどの場合と同様)、XHRはHTTP応答に反応します。エラーをキャプチャするにはtry
/catch
およびdone()
/fail()
コールバックを使用できます。 JSONでステータスレポートをカプセル化することがそれ以上に便利であることはわかりません。
以下はinstagramが使用しているjson形式です。
{
"meta": {
"error_type": "OAuthException",
"code": 400,
"error_message": "..."
}
"data": {
...
},
"pagination": {
"next_url": "...",
"next_max_id": "13872296"
}
}
それが価値があるもののために私はこれを違うやり方でする。成功した呼び出しはただJSONオブジェクトを持っています。 trueを示すsuccessフィールドとJSONオブジェクトを持つペイロードフィールドを含む、より高いレベルのJSONオブジェクトは必要ありません。適切なJSONオブジェクトを200で返すか、ヘッダーのHTTPステータスに200の範囲内で適切なものを返します。
ただし、エラーがある場合(400ファミリーの中にあるもの)、整形式のJSONエラーオブジェクトを返します。たとえば、クライアントが電子メールアドレスと電話番号を使用してユーザーにPOSTを実行していて、そのうちの1つが不正な形式のものである場合(つまり、基盤となるデータベースに挿入できません)
{
"description" : "Validation Failed"
"errors" : [ {
"field" : "phoneNumber",
"message" : "Invalid phone number."
} ],
}
ここで重要なことは、 "field"プロパティがJSONフィールドと正確に一致しなければならないということです。これは検証できませんでした。これにより、クライアントは自分の要求で何が悪かったのかを正確に知ることができます。また、 "message"は要求のロケールにあります。 "emailAddress"と "phoneNumber"の両方が無効な場合、 "errors"配列に両方のエントリが含まれます。 409(Conflict)JSONレスポンスボディは次のようになります。
{
"description" : "Already Exists"
"errors" : [ {
"field" : "phoneNumber",
"message" : "Phone number already exists for another user."
} ],
}
HTTPステータスコードとこのJSONを使用すると、クライアントは確定的な方法でエラーに対応するために必要なすべてを備え、HTTPステータスコードを完全に置き換えることを試みる新しいエラー標準を作成することはありません。これらは400エラーの範囲でのみ発生します。 200の範囲の何のためにでも私は適切であるものを何でも返すことができます。私にとってそれはHALのようなJSONオブジェクトですが、それはここでは問題になりません。
私が追加することについて考えたことの一つは、 "errors"配列エントリまたはJSONオブジェクト自体のルートのいずれかにある数値エラーコードでした。しかし今のところ我々はそれを必要としていません。
RFC 7807:HTTP APIの問題の詳細 は現在のところ公式の標準に最も近いものです。
Google、Facebook、Twitter、Amazonなど、大手ソフトウェア大手企業の残りのapiレスポンスフォーマットについては合意されていませんが、上記の回答では多くのリンクが提供されています。
APIのニーズは異なる可能性があるため、全員を参加させ、何らかの形式に同意することは非常に困難です。あなたのAPIを使用している何百万ものユーザーがいる場合、なぜあなたはあなたの応答フォーマットを変更しますか?
以下は、グーグル、ツイッター、アマゾン、そしてインターネットに関するいくつかの記事にヒントを得たレスポンスフォーマットです。
https://github.com/adnan-kamili/rest-api-response-format
Swaggerファイル:
JSONのポイントは、それが完全に動的かつ柔軟であるということです。それは単なる1つのノードに根ざした、直列化されたJavaScriptオブジェクトと配列のセットにすぎないため、好きなように曲げてください。
ルートノードのタイプはあなた次第です、それに含まれるものはあなた次第です、あなたがメタデータをレスポンスと共に送るかどうかはあなた次第です、mime-typeをapplication/json
に設定するかtext/plain
はそのままにしておくかあなたは(あなたがEdgeのケースをどう処理するかを知っている限り)。
あなたが好きな軽量スキーマを構築しましょう。
個人的に、私は、オンラインゲーム用のアナリティクストラッキングとmp3/oggサービング、イメージギャラリーサービング、テキストメッセージングとネットワークパケット、そしてブログ投稿とブログコメント all 持っている 非常に異なる要件 何が送信され、何が受信され、それらがどのように消費されるべきであるかという点で。
それで私がそれをすべてするとき、私が欲しいと思う最後のことはそれぞれがXML2.0かいくつかに基づいている同じボイラープレート標準に従うようにすることを試みることです。
そうは言っても、 you に意味があり、よく考えられているスキーマを使用するために言うべきことはたくさんあります。
いくつかのAPIレスポンスを読み、好きなことを書き留めて、嫌いなことを批評し、それらの批判を書き留めて、なぜ彼らが間違った方法でこすってしまうのかを理解してから必要。
JSON-RPC 2.0 は標準的なリクエストとレスポンスのフォーマットを定義しており、REST APIを使った作業を終えた後は一気に新鮮な空気になります。
2番目の例については、 JSON仕様では禁止されています :
メンバーのデータとエラーは同じドキュメントに共存してはいけません。
私は少し研究をしましたが、エラー(例外)を返すための最も一般的な形式はこの形式の構造であることがわかりました。
{
"error": {
"code": "400",
"message": "main error message here",
"target": "approx what the error came from",
"details": [
{
"code": "23-098a",
"message": "Disk drive has frozen up again. It needs to be replaced",
"target": "not sure what the target is"
}
],
"innererror": {
"trace": [ ... ],
"context": [ ... ]
}
}
}
これは、OASISデータ標準 OASIS OData で提案されているフォーマットであり、そこで最も標準的なオプションのように思われますが、現時点ではどの標準の高い採用率もないようです。この形式はJSON-RPC仕様と一致しています。
これを実装している完全なオープンソースライブラリは、 Mendocino JSON Utilities にあります。このライブラリはJSONオブジェクトと例外をサポートします。