web-dev-qa-db-ja.com

標準のJSON APIレスポンスフォーマット

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!"
  }
}
597
FtDRbwLXw6

はい、いくつかの標準があります(標準の定義にはいくつかの自由がありますが)。

  1. JSON API - JSON APIは、応答だけでなく、リソースの作成と更新もカバーしています。
  2. JSend - 単純で、おそらくあなたがすでにやっていること。
  3. OData JSONプロトコル - 非常に複雑。
  4. _ hal _ - ODataに似ていますが、 _ hateoas _ になることを目指しています。

JSON APIの記述形式もあります。

553
Adam Gent

Google JSONガイド

成功応答の返信 data

{
  "data": {
    "id": 1001,
    "name": "Wing"
  }
}

エラーレスポンスリターン error

{
  "error": {
    "code": 404,
    "message": "ID not found"
  }
}

クライアントがJSの場合は、if ("error" in response) {}を使用してエラーがないかどうかを確認できます。

159
Steely Wing

私は事実上の標準が実際には出現していないと思います(そして決してそうはしないかもしれません)。それにもかかわらず、これが私の考えです。

リクエスト成功:

{
  "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」を追加することもできます。

103
trungly

あなたが疑問に思っているのがRESTウェブサービスのデザイン、そしてより正確には成功/エラーに関するものであるとしましょう。

3種類のデザインがあると思います。

  1. エラーがあったかどうかを示すために のみHTTPステータスコード を使用してください(通常はそれで十分です)。

    • 長所:それはあなたのAPIから独立した標準です。
    • 短所:実際に起こったことについての情報が少ない。
  2. HTTP Status + json body を使用します(エラーであっても)。エラー(例:コード、メッセージ、理由、タイプなど)に対して統一された構造を定義し、それがエラーに使用された場合、それが成功した場合は予想されるJSON応答を返すだけです。

    • 長所:既存のHTTPステータスコードを使用し、エラーを説明するJSONを返すので、依然として標準です(何が起こったのかについての詳細な情報を提供します)。
    • 短所:出力JSONは、それがエラーか成功かによって異なります。
  3. 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 +エラーも含むレスポンスオブジェクトに返すオブジェクトをカプセル化する必要があるので、それほどいい方法ではありません。

74
eugen

私はこれが標準であると主張するのは傲慢ではないので、私は「私が好む」形式を使用します。

私は簡潔な回答を好みます(/ 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でステータスレポートをカプセル化することがそれ以上に便利であることはわかりません。

18
Bojan Markovic

以下はinstagramが使用しているjson形式です。

{
    "meta": {
         "error_type": "OAuthException",
         "code": 400,
         "error_message": "..."
    }
    "data": {
         ...
    },
    "pagination": {
         "next_url": "...",
         "next_max_id": "13872296"
    }
}
17
Muhammad Amin

それが価値があるもののために私はこれを違うやり方でする。成功した呼び出しはただ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オブジェクト自体のルートのいずれかにある数値エラーコードでした。しかし今のところ我々はそれを必要としていません。

13
robert_difalco

RFC 7807:HTTP APIの問題の詳細 は現在のところ公式の標準に最も近いものです。

12
Berislav Lopac

Google、Facebook、Twitter、Amazonなど、大手ソフトウェア大手企業の残りのapiレスポンスフォーマットについては合意されていませんが、上記の回答では多くのリンクが提供されています。

APIのニーズは異なる可能性があるため、全員を参加させ、何らかの形式に同意することは非常に困難です。あなたのAPIを使用している何百万ものユーザーがいる場合、なぜあなたはあなたの応答フォーマットを変更しますか?

以下は、グーグル、ツイッター、アマゾン、そしてインターネットに関するいくつかの記事にヒントを得たレスポンスフォーマットです。

https://github.com/adnan-kamili/rest-api-response-format

Swaggerファイル:

https://github.com/adnan-kamili/swagger-sample-template

8
adnan kamili

JSONのポイントは、それが完全に動的かつ柔軟であるということです。それは単なる1つのノードに根ざした、直列化されたJavaScriptオブジェクトと配列のセットにすぎないため、好きなように曲げてください。

ルートノードのタイプはあなた次第です、それに含まれるものはあなた次第です、あなたがメタデータをレスポンスと共に送るかどうかはあなた次第です、mime-typeをapplication/jsonに設定するかtext/plainはそのままにしておくかあなたは(あなたがEdgeのケースをどう処理するかを知っている限り)。

あなたが好きな軽量スキーマを構築しましょう。
個人的に、私は、オンラインゲーム用のアナリティクストラッキングとmp3/oggサービング、イメージギャラリーサービング、テキストメッセージングとネットワークパケット、そしてブログ投稿とブログコメント all 持っている 非常に異なる要件 何が送信され、何が受信され、それらがどのように消費されるべきであるかという点で。

それで私がそれをすべてするとき、私が欲しいと思う最後のことはそれぞれがXML2.0かいくつかに基づいている同じボイラープレート標準に従うようにすることを試みることです。

そうは言っても、 you に意味があり、よく考えられているスキーマを使用するために言うべきことはたくさんあります。
いくつかのAPIレスポンスを読み、好きなことを書き留めて、嫌いなことを批評し、それらの批判を書き留めて、なぜ彼らが間違った方法でこすってしまうのかを理解してから必要。

7
Norguard

JSON-RPC 2.0 は標準的なリクエストとレスポンスのフォーマットを定義しており、REST AP​​Iを使った作業を終えた後は一気に新鮮な空気になります。

4
dnault

2番目の例については、 JSON仕様では禁止されています

メンバーのデータとエラーは同じドキュメントに共存してはいけません。

0
Soapr

私は少し研究をしましたが、エラー(例外)を返すための最も一般的な形式はこの形式の構造であることがわかりました。

{
   "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オブジェクトと例外をサポートします。

詳細は、 JSONでのエラー処理REST AP​​I - の私のブログ投稿で説明されています

0
AgilePro