RESTful APIで応答として配列を返す最良の方法は何ですか?


40

このようなリソースがあるとします

book:
    type: object
    properties:
        author: {type: string}
        isbn: {type: string}
        title: {type: string}

books:
    type: array
    items: book

したがって、誰かがGET本のリソースを作成すると、次のように返されます

[{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
 {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]

職場の誰かから、推奨されるRESTプラクティスは、常にJSONオブジェクトとして応答を返すことであると聞きました。つまり、スキーマbooksは次のようになります。

books:
    type: object
    properties:
        list:
            type: array
            items: book

それで、今、応答は次のようになります。

{
    "list": [{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
             {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]
}

これらのうち、RESTのベストプラクティスはどれですか?


1
JSON RESTfulは何ですか?htmlを確実に返す必要がありますか?
ユアン

3
@Ewan:ペイロードは重要ではありません。それがMIMEタイプの目的です。
ロバートハーベイ

1
RESTのベストプラクティスでもありません。RESTはHATEOASで構成されています。つまり、APIの発見可能性を意味します。HALまたはJSON-LDを検索します。
フロリアンマーゲイン

Json-ld:WCFに向けてゆっくりと作業中
ユアン

オブジェクト内のラッピングJSON配列を読んだことから、古いブラウザーで報告された脆弱性に対する防御策があります-haacked.com/archive/2009/06/25/json-hijacking.aspx。これは、今日の現代のブラウザで修正されたようです。残念私の推測より良い安全な...
Gishu

回答:


35

実際には、2番目のオプションがベストプラクティスです。これは、配列を返すだけではリソースをまったく拡張できないためです。

例:すべてのレコードのカウントを追加する必要がある場合、配列のみのアプローチは既に完了しています。

1つのリストAPIでそれが発生する場合は、一貫性を維持してすべてのオブジェクトを作成すると、APIの一貫性が高まり、開発者にとって使いやすくなります。

例:開発者がAPIを使用してリストページと詳細ページを表示するための汎用コードを記述したとします。彼は例外を作成することを望んでいません。なぜなら、それが配列である場合や、リストプロパティを持つオブジェクトである場合があるからです。

この答えは全体として、休息、ハテオアなどのプロトコルに関する原則とは何の関係もありませんが、クライアントに送信する必要のあるデータについては真実です。たとえばhateosに従うことを決めた場合は、当然、それらの標準に準拠します(これもオブジェクトです)。


3
「データについて本物であること」に対する+1(そして、RESTにはより技術的で正確な定義があることを認識しながら)。
threed

8

両方

[{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},{"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]

そして

{
    "list": [{"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
         {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}]
}

有効なJsonです。不要な場合は「リスト」を追加する必要はないと思います。それに続くものはリストではなく配列であるため、紛らわしいかもしれません。

RESTのベストプラクティスは?APIは、Acceptヘッダーに設定されているものに適切な応答を提供し、適切なドキュメントを提供する必要があります。


7

応答をJSONに準拠させる理由は、JSONが事実上の標準だからです。JSONパーサーを備えたどの言語でも簡単に解析できます。JavaScriptを使用している場合は、JavaScriptがネイティブに理解するため、パーサーは必要ありません。

言い換えれば、JSONに準拠させると、独自のパーサーを記述する必要がなくなります。さらに、次の開発者がサービスを使用するソフトウェアを作成しても驚くことはありません。

RESTはJSONスキーマとは何の関係もありません。RESTの観点からは、どちらのスキーマでも受け入れられます。


9
それは質問に答えますか?「json配列またはjsonオブジェクトをルートとして使用する必要がありますか?」と読みました。どちらもjsonパーサーで解析できるので、あなたの答えは彼らが決めるのを助けません。
CodesInChaos

それは問題ではありません。回答を更新しました。
ロバートハーベイ

RESTについて話している場合、応答のみに基づいて、他の帯域外情報に基づいて、さらなるリソースの発見と操作のためのハイパーメディアコントロールを提供できる限り、スキーマは重要ではありません... OPで言及されている形式はどれも実行していないようです。
トニエズヴィエズ

...and if you're using JavaScript, you don't even need a parser since JavaScript understands it natively.はい、そうです。JSONはJavaScriptのサブセットですがeval、パーサーを使用する代わりに呼び出すと、すぐに悪意のあるコードを含む「JSON」に対して脆弱になり、解析はevalとにかく効率的です。
ドーバル

5

単一の無意味なキー「リスト」と配列値を持つ辞書は無意味です-代わりに配列を返します。

同じサービスが書籍、CD、またはDVDを返すことができる場合、キー「books」と配列値を持つ辞書を返すことができます。DVDの配列を持つ別のキー「DVD」がある場合があります。たとえば、顧客がすべての購入のリストを照会できる場合。

応答が書籍のリストとしてのみ解釈されることが確実な場合(リクエストが「書籍のリストをくれ」と言った場合)、配列だけで問題ありません。


5

2番目のオプションは、セキュリティ上の理由からも好ましい方法です。古いブラウザには、Webページ上の他のJavaScriptコードがJSON配列として返された場合にデータを盗むことができるセキュリティ上の脆弱性があります。そのため、歴史的にベストプラクティスはJSON配列を返さないことでした。実際、配列を渡すときに「json-ify」関数がデフォルトでオプション2を選択するフレームワークがいくつかありました。

https://stackoverflow.com/questions/3503102/what-are-top-level-json-arrays-and-why-are-they-a-security-risk

http://ejohn.org/blog/re-securing-json/


1

どちらもjsonであり、RESTに準拠しています。あなたのケースの変更リストで、本の回答をよりわかりやすくします。またはこのようなもの:

{ "responceObject" : {

   results : 2,

    "Books": [
        {"author": "Dan Brown", "isbn": "123456", "title": "Digital Fortress"},
        {"author": "JK Rowling", "isbn": "234567", "title": "Harry Potter and the Chamber of Secrets"}
    ]

}}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.