Bir dizi bir RESTful API'de yanıt olarak döndürmenin en iyi yolu nedir?


40

Bunun gibi kaynaklarımız olduğunu varsayalım.

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

books:
    type: array
    items: book

Yani, birileri GETkitaplar kaynağında bir şey yaptığında, aşağıdakileri iade ediyor oluruz

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

Demek istiyorum ki tavsiye edilen DİNLENME uygulama JSON nesneleri her zaman olduğu gibi yanıtları dönmek olduğunu iş yerinde birinden duydum yönelik şema booksşu şekilde görünür,

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

Öyleyse, şimdi, cevap şöyle gözükecekti:

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

Bunlardan hangisi en iyi REST uygulamasıdır?


1
JSON RESTful nedir? mutlaka html döndürmelisin?
Ewan

3
@Ewan: Yükün önemi yok. MIME tipleri bunun için var.
Robert Harvey,

1
Hiçbiri REST için en iyi uygulama değildir. REST, API'nizin keşfedilebilirliği anlamına gelen HATEOAS'tan yapılmıştır. HAL veya JSON-LD'ye bakın.
Florian Margaine

Json-ld: WCF'ye doğru yavaşça çalışıyor
Ewan

Bir nesnenin içindeki sarma JSON dizilerini okuduklarımdan, eski tarayıcılarda bildirilen bir güvenlik açığına karşı savunmalı bir önlemdir - haacked.com/archive/2009/06/25/json-hijacking.aspx . Bu, bugünün modern tarayıcılarında düzeltilmiş görünüyor. Üzgünüm daha iyi güvenli sanırım ..
Gishu

Yanıtlar:


35

Uygulamada ikinci seçenek en iyi uygulamadır. Bunun nedeni, sadece bir dizi döndürdüğünüzde kaynağı hiç uzatamazsınız.

Örneğin: Tüm kayıtların sayısını eklemeniz gerekirse, zaten sadece dizi yaklaşımı ile işiniz bitmiştir.

Eğer api bir listede bu gerçekleşirse, onu tutarlı tutmak istersiniz, bu yüzden tüm nesneleri bir nesneye dönüştürün, api'niz geliştiriciler için daha tutarlı ve kullanımı daha kolay hale gelir.

Örneğin: Bir geliştiricinin liste ve ayrıntı sayfalarını göstermek için API'nizi kullanmak için genel kod yazdığını varsayalım. Bir istisna oluşturmak istemiyor çünkü bazen bir dizi ve bazen de list özelliğine sahip bir nesne.

Toplamda bu cevabın dinlenme, hateolar ve diğer protokoller ile ilgili prensipleri ile ilgisi yoktur, sadece müşteriye göndermeniz gereken veriler konusunda gerçek olmaktır. Örneğin hateoları takip etmeye karar verirseniz, kurs dışı standartlarına uyun (aynı zamanda btw nesneleridir).


3
"Veriler hakkında gerçek olmak" için +1 (ve hala REST için daha teknik, daha doğru bir tanım olduğunu kabul ederken).
Threed

8

Her ikisi de

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

ve

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

geçerli Json. Gerekmediği takdirde "liste" eklemelisin sanırım, kafa karıştırıcı olabilir, çünkü onu takip eden liste yerine bir dizidir.

En iyi REST uygulaması? API, Üstbilgi Kabul Et ayarında belirtilenlere uygun yanıt vermeli ve ayrıca iyi belgeler sağlamalıdır.


7

Yanıtınızı JSON'a uyumlu hale getirmenizin nedeni , JSON'un bir defacto standardı olmasıdır; JSON ayrıştırıcısına sahip herhangi bir dil önemsiz bir şekilde ayrıştırır ve JavaScript kullanıyorsanız, JavaScript yerel olarak anladığı için bir ayrıştırıcıya bile ihtiyacınız yoktur.

Başka bir deyişle, onu JSON uyumlu hale getirin ve kendi ayrıştırıcınızı yazmak zorunda kalmayacaksınız. Ayrıca, bir sonraki geliştirici hizmeti tüketen bir yazılım yazdığında sürpriz olmaz.

REST, JSON şemanızla ilgisi yoktur. Her iki şema da REST açısından kabul edilebilir.


9
Bu soruya cevap veriyor mu? "Json dizisi mi yoksa kök olarak bir json nesnesi mi kullanmalıyım?" Olarak okudum. Her ikisi de json ayrıştırıcılarıyla ayrıştırılabilir, bu nedenle cevabınız karar vermelerine yardımcı olmaz.
CodesInChaos

O zaman önemli değil. Cevabımı güncelledim.
Robert Harvey,

Eğer REST hakkında konuşuyorsak, şema sadece cevaba dayanarak başka kaynakların keşfi ve manipülasyonu için hiper medya kontrolleri sağlama kabiliyetine sahip olduğu sürece önemli değildir; OP tarafından belirtilen formatların hiçbiri görünmüyor.
toniedzwiedz

...and if you're using JavaScript, you don't even need a parser since JavaScript understands it natively.Evet, evet ve hayır. JSON bir JavaScript alt kümesidir, ancak evalayrıştırıcı kullanmak yerine çağrı yapmak sizi derhal zararlı kod içeren "JSON" için savunmasız hale getirir ve ayrıştırma evalher durumda olduğundan çok daha etkilidir .
Doval

5

Tek bir anlamsız anahtar "liste" ve bir dizi değerine sahip bir sözlük anlamsızdır - bunun yerine bir dizi döndür.

Aynı servis kitapları, CD'leri veya DVD'leri geri getirebiliyorsa, "anahtar kelimeler" ve dizi değeri olan bir sözlük verebilirsin. Bir dizi DVD ile başka bir "DVD" anahtarı olabilir. Örneğin, bir müşteri tüm alımlarının bir listesini isteyebilirse.

Cevabın sadece kitap listesi olarak yorumlanacağından eminseniz (eğer talep "bana bir kitap listesi ver" ise) sadece bir dizi iyidir.


5

İkinci seçenek, güvenlik nedeniyle de tercih edilen yöntemdir. Daha eski tarayıcılar, JSON dizisi olarak döndürüldüğünde, web sayfasındaki diğer javascript kodunun verilerinizi çalmasına izin veren bir güvenlik açığına sahiptir. Bu yüzden tarihsel olarak en iyi uygulama JSON dizilerini döndürmemek oldu. Aslında, bir dizide geçtiğinizde "json-ify" işlevi varsayılan olarak seçenek 2'yi seçen bazı çerçeveler vardı.

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

İkisi de json ve REST'e bağlı. Davanızı değiştirdiğinizde, kitaptaki yanıtı daha açıklayıcı hale getirebilirim. Veya böyle bir şey:

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

}}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.