Apa cara terbaik untuk mengembalikan array sebagai respons di RESTful API?

41

Anggaplah kita memiliki sumber daya seperti ini,

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

books:
    type: array
    items: book

Jadi, ketika seseorang membuat GETsumber daya di buku, kami akan mengembalikan yang berikut

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

Saya mendengar dari seseorang di tempat kerja bahwa praktik REST yang disarankan adalah selalu mengembalikan respons sebagai objek JSON, yang berarti skema kami booksakan terlihat seperti ini,

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

Jadi, sekarang, respons akan terlihat seperti ini,

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

Manakah dari ini yang merupakan praktik REST terbaik?

borncrusader
sumber
1
Apakah JSON RESTful? Anda harus mengembalikan html tentunya?
Ewan
3
@ Ewan: Muatannya tidak masalah. Untuk itulah tipe MIME diperuntukkan.
Robert Harvey
1
Tidak ada praktik terbaik untuk REST. REST dibuat dari HATEOAS, yang berarti dapat ditemukannya API Anda. Cari HAL atau JSON-LD.
Florian Margaine
Json-ld: berjalan perlahan menuju WCF
Ewan
Dari apa yang saya baca array JSON pembungkus di dalam suatu objek adalah tindakan defensif terhadap kerentanan yang dilaporkan di browser lama - haacked.com/archive/2009/06/25/json-hijacking.aspx . Ini tampaknya telah diperbaiki di browser modern saat ini. Lebih baik aman daripada menyesal kurasa ..
Gishu

Jawaban:

35

Dalam praktiknya pilihan kedua adalah praktik terbaik. Alasan untuk ini adalah bahwa Anda tidak dapat memperpanjang sumber daya sama sekali ketika Anda hanya mengembalikan array.

Sebagai contoh: Jika Anda perlu menambahkan hitungan semua catatan Anda sudah selesai dengan pendekatan array saja.

Jika itu terjadi dalam satu daftar api maka Anda ingin tetap konsisten sehingga buat semua objek maka api Anda menjadi lebih konsisten dan lebih mudah digunakan untuk pengembang.

Sebagai contoh: Katakanlah seorang pengembang menulis kode generik untuk menggunakan api Anda untuk menampilkan daftar dan halaman detail. Dia tidak ingin membangun pengecualian karena kadang-kadang array dan kadang-kadang objek dengan properti daftar.

Jawaban ini secara total tidak ada hubungannya dengan prinsip-prinsip tentang istirahat, kebencian dan protokol lain tetapi hanya menjadi nyata tentang data yang Anda perlu kirim ke klien. Jika Anda memutuskan untuk mengikuti, misalnya, hateos maka tentu saja berpegang teguh pada standar mereka (yang juga objek btw).

Luc Franken
sumber
3
+1 untuk "menjadi nyata tentang data" (dan sementara masih mengakui bahwa ada definisi yang lebih teknis, lebih akurat untuk REST).
threed
9

Kedua

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

dan

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

adalah Json yang valid. Saya tidak berpikir Anda harus menambahkan "daftar" jika tidak diperlukan, bahkan mungkin membingungkan karena apa yang mengikutinya adalah sebuah array, bukan daftar.

Praktik REST terbaik? API harus memberikan respons yang tepat untuk apa pun yang diatur dalam header Terima, dan juga dokumentasi yang baik.

imel96
sumber
7

Alasan Anda membuat respons Anda sesuai dengan JSON adalah bahwa JSON adalah standar de facto; bahasa apa pun dengan parser JSON dapat dengan mudah menguraikannya, dan jika Anda menggunakan JavaScript, Anda bahkan tidak memerlukan parser karena JavaScript memahaminya secara asli.

Dengan kata lain, buatlah agar sesuai dengan JSON, dan Anda tidak perlu menulis parser Anda sendiri. Lebih lanjut, tidak akan ada kejutan ketika pengembang berikutnya menulis perangkat lunak yang mengkonsumsi layanan.

REST tidak ada hubungannya dengan skema JSON Anda. Skema mana pun dapat diterima, dari perspektif REST.

Robert Harvey
sumber
9
Apakah itu menjawab pertanyaan? Saya membacanya sebagai "Haruskah saya menggunakan json array atau objek json sebagai root?". Keduanya dapat diuraikan dengan parser json, jadi jawaban Anda tidak membantu mereka memutuskan.
CodesInChaos
Maka itu tidak masalah. Saya telah memperbarui jawaban saya.
Robert Harvey
Jika kita berbicara tentang REST, skema itu tidak masalah asalkan itu mampu memberikan kontrol hypermedia untuk penemuan dan manipulasi sumber daya lebih lanjut berdasarkan pada respon saja dan tidak ada informasi lain, out-of-band ... yang tampaknya tidak ada format yang disebutkan oleh OP.
toniedzwiedz
...and if you're using JavaScript, you don't even need a parser since JavaScript understands it natively.Ya dan tidak. JSON adalah himpunan bagian dari JavaScript tetapi memanggil evaldaripada menggunakan parser segera membuat Anda rentan terhadap "JSON" yang berisi kode berbahaya, dan parsing kemungkinan besar jauh lebih efisien daripada apa pun eval.
Doval
5

Kamus dengan "daftar" kunci yang tidak berarti dan nilai array tidak ada artinya - kembalikan array.

Jika layanan yang sama dapat mengembalikan buku, CD atau DVD, maka Anda dapat mengembalikan kamus dengan "buku" kunci dan nilai array. Mungkin ada "DVD" kunci lain dengan berbagai DVD. Misalnya jika seorang pelanggan dapat menanyakan daftar semua pembelian mereka.

Jika Anda yakin bahwa responsnya hanya akan ditafsirkan sebagai daftar buku (jika permintaan mengatakan "berikan saya daftar buku") maka hanya array yang baik-baik saja.

gnasher729
sumber
5

Opsi kedua juga merupakan metode yang dipilih untuk alasan keamanan. Browser yang lebih lama memiliki kerentanan keamanan yang memungkinkan kode javascript lain pada halaman web untuk mencuri data Anda jika dikembalikan sebagai array JSON. Jadi secara historis praktik terbaik adalah tidak mengembalikan array JSON. Bahkan, ada beberapa kerangka kerja yang fungsi "json-ify" memilih opsi 2 secara default ketika Anda meneruskan dalam sebuah array.

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/

Membuang
sumber
1

keduanya json dan mematuhi REST. Saya akan membuat responsnya lebih deskriptif, dalam kasus Anda, daftar perubahan ke buku. Atau sesuatu seperti ini :

{ "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"}
    ]

}}
MeganFoxObama
sumber