REST API - API Yuvalanmış JSON Nesnelerini Döndürmeli mi?


37

JSON API'lerine gelince, yanıtları düzeltmek ve iç içe geçmiş JSON nesnelerinden kaçınmak iyi bir uygulama mıdır?

Örnek olarak IMDb'ye benzer bir API'miz var ama video oyunları için. Oyun ve Platformları haritalayan bir kaç varlık, Oyun, Platform, ESRBRating ve GamePlatformMap vardır.

Diyelim ki, ID 1 ile oyunu alan / oyun / 1'i talep edelim ve oyun nesnesini platformlar ve esrbRating ile iç içe geçirir.

{
  "id": 1,
  "title": "Game A",
  "publisher": "Publisher ABC",
  "developer": "Developer DEF",
  "releaseDate": "2015-01-01",
  "platforms": [
    {"id":1,"name":"Xbox"},
    {"id":2,"name":"Playstation"}
  ],
  "esrbRating": {
    "id": 1,
    "code": "E",
    "name": "Everyone"
  }
}

JPA / Hibernate gibi bir şey kullanıyorsanız, FETCH.EAGER olarak ayarlanmışsa, sizin için otomatik olarak bunu yapabilir.

Diğer seçenek basitçe API ve daha fazla bitiş noktası eklemektir.

Bu durumda / oyun / 1 istendiğinde sadece oyun nesnesi döndürülür.

{
  "id": 1,
  "title": "Game A",
  "publisher": "Publisher ABC",
  "developer": "Developer DEF",
  "releaseDate": "2015-01-01",
}

Platformları ve / veya ESRBRating'i istiyorsanız aşağıdakileri çağırmanız gerekir:

/ oyun / 1 / platform / oyun / 1 / esrb

Bu yöntem, istemcinin ihtiyaç duyduğu verilere ve ne zaman ihtiyaç duyduklarına bağlı olarak sunucuya birkaç çağrı daha ekleyebilecek gibi görünüyor.

Bunun gibi bir şeyin geri döndüğü yerde yaşadığım son bir düşünce vardı.

{
  "id": 1,
  "title": "Game A",
  "publisher": "Publisher ABC",
  "developer": "Developer DEF",
  "releaseDate": "2015-01-01",
  "platforms": ["Xbox","Playstation"]
}

Ancak bu, kimlik numaralarına ihtiyaç duymadıklarını veya bu platform nesneleriyle ilişkili olabilecek diğer bilgilerin ne olduğunu varsayar.

Genel olarak, API'nizden döndürülen JSON nesnelerinizi yapılandırmanın en iyi yolunun ne olduğunu soruyorum. Kurumlarınıza mümkün olduğunca yakın kalmaya mı çalışmalısınız yoksa Etki Alanı Nesneleri veya Veri Aktarım Nesneleri'ni kullanmanız uygun mudur? Metodların, veri erişim katmanı üzerinde daha fazla iş veya müşteri için daha fazla iş olduğu gibi ticari teklifleri olacağını anlıyorum.

Ayrıca, Spring MVC'yi API için arka uç teknolojisi olarak kullanmaya ilişkin bir cevap duymak isterim, ya da kalıcılık için JPA / Hibernate ya da MyBatis.


6
Varsa, hangi nesnelere gömülü nesneler döndürüyorsunuz? Gömülü nesneleri tek tek farklı uç noktalardan döndürmek, oldukça can sıkıcı bir hal alacaktır (yavaş söz değil).
Robert Harvey,

1
Şahsen buna itirazım yok. Neyin en iyi uygulama olarak kabul edildiğinin farkında değilim. Bir meslektaşım, AngularJS'deki gömülü nesnelerle çalışmanın doğrudan bir öneme sahip olmadığını ve nihayetinde AngularJS uygulamasının Ember'in API'yi tüketmesini ister. Bunun bir etkisi olup olmayacağını bilmek için Açısal veya Ember hakkında yeterince bilgim yok.
greyfox

3
Cevap etki alanı nesnelerini, DTO'ları, ViewModel nesnelerini veya KitchenSink nesnelerini döndürmek isteyip istemediğinize bağlı olacaktır. Hangi nesneye döndüğünüz, uygulamanızın neye ihtiyacı olduğuna ve belirtilen nesnenin İnternet üzerinden nasıl davrandığına göre belirlenir. Örnek: Bir web sayfasını bir faturadaki verilerle doldurmaya çalışıyorsanız, büyük olasılıkla ihtiyacınız olan her şeyi içeren bir nesneyi döndüreceksiniz (satır öğelerinde AJAXing'i planlamadığınız sürece).
Robert Harvey,

Bu durumda, bir oyun talep ettiğinizde muhtemelen türleri, platformları ve ESRBRating'i bilmek isteyeceksinizdir. Bu mantıklı. Java açısından tasarım açısından, JPA'nın sahip olduğu Varlık paketine ve ardından iş nesneleri / DTO'nun kullanıcıya geri gönderildiği bir etki alanı paketine sahip olmanızı tavsiye eder misiniz?
greyfox

1
Sunucuya yapılan aramalar pahalıdır. Birden fazla çağrı kullanarak veri göndermenizi gerektiren bir API, çoğu kişi gereksiz bilgi döndürdüğünde bile, bir çağrıdaki her şeyi almanıza izin veren bir API'den daha yavaş olacaktır.
Robotu

Yanıtlar:


11

Başka bir alternatif (HATEOAS kullanarak). Bu basittir, çoğunlukla pratikte HATEOAS kullanımınıza bağlı olarak json'a bir link etiketi eklersiniz.

http://api.example.com/games/1:

{
  "id": 1,
  "title": "Game A",
  "publisher": "Publisher ABC",
  "developer": "Developer DEF",
  "releaseDate": "2015-01-01",
  "platforms": [
    {"_self": "http://api.example.com/games/1/platforms/53", "name": "Playstation"},
    {"_self": "http://api.example.com/games/1/platforms/34", "name": "Xbox"},
  ]
}

http://api.example.com/games/1/platforms/34:

{
  "id": 34,
  "title": "Xbox",
  "publisher": "Microsoft",
  "releaseDate": "2015-01-01",
  "testReport": "http://api.example.com/games/1/platforms/34/reports/84848.pdf",
  "forms": [
    {"type": "edit", "fields: [] },
  ]
}

Elbette tüm verileri tüm listelere gömebilirsiniz, ancak bu muhtemelen çok fazla veri olacaktır. Bu şekilde, gerekli verileri katıştırabilir ve daha sonra gerçekten çalışmak istiyorsanız daha fazla yükleyebilirsiniz.

Teknik uygulama önbellek içerebilir. Platformların bağlantılarını ve adlarını oyun nesnesindeki önbellekte saklayabilir ve platform api'lerini yüklemek zorunda kalmadan anında gönderebilirsiniz. Sonra gerektiğinde onu yükleyebilirsiniz.

Örneğin bazı form bilgileri eklediğimi görüyorsunuz. Bunu, ayrıntılı bir json nesnesinde, oyun listesine yüklemek isteyeceğinizden çok daha fazla bilgi olabileceğini göstermek için yaptım.


Devlet olmadığından teknik olarak HATEOS olduğunu sanmıyorum.
RibaldEddie

Evet, bu işlem hakkında kesin bir kelime bilmiyorum. HATEOS genel olarak diğer API'lerde bağlantı kurmak için kullanılıyor, ancak bunun devletle de ilgisi olduğunu kabul ediyorum. Gerçi uygulama fikri aynı olacaktır. Burada, bir örnek tarafından nasıl kullanılabileceği hakkında biraz daha fazlasını görüyorsunuz: stormpath.com/blog/linking-and-resource-expansion-rest-api-tips
Luc Franken,

Yine de iyi bir fikir!
RibaldEddie

1
İstemci ve api'nin kendisiyle (iç api demek) arasında bir uyum olduğu bir API geliştiriyorsanız, başka bir kaynağa bağlantılar sağlamak yerine iç içe (veya düzleştirilmiş) bir yanıt döndürmek daha mantıklı olabilir; istenmeyen olabilir.
Bruno

@ bruno evet, ancak bir limit ile: Daha büyük sistemlerde, ilgili tüm nesneleri tam olarak sağlayamazsınız veya istemeyebilirsiniz. Varsayılan olarak eklediğiniz alanlar isteğe bağlıdır, api'nizin kullanımına bağlı olarak bunları seçebilirsiniz. Bu yüzden, bu durumda yüzlerce alana sahip platformunuz olabilir, kullanım durumu bir platform seçmek için bir seçim kutusu gösteriyor. O zaman platformun ismini eklemek mantıklı ama platformun finansal detaylarına ihtiyaç duymuyor.
Luc Franken

16

REST API tasarımı söz konusu olduğunda, bu temel sorulardan biri. Her tasarımcı bu soruyu ilk gün kendilerine soruyor. Üzgünüz ama cevap "bağlıdır". Her yaklaşımın avantajları ve dezavantajları vardır ve bir karar vermeniz ve onunla devam etmeniz yeterlidir.


10
Bu hiç yardımcı değil. OP, “her şeyin yaklaşımının artıları ve eksileri olduğunu” biliyordu. Hangi şeylere bağlı olduğunu açıklamalısınız veya en azından biraz örnek vermelisiniz.
Pratik Singhal

5

Burada sunulan yaklaşımı https://www.slideshare.net/stormpath/rest-jsonapis

Kısacası, iç içe kaynağı ana kaynağa bağlantılar olarak ekleyin, bu arada ana uç noktasında bir genişleme parametresi sağlayın.

Benim düşünceme göre, bu çoğu durumda verimli ve esnek bir yoldur.


2
Bu yaklaşımı seviyorum. Merak eden herkes için bu, bağlantılı slayt gösterisindeki SLIDE 57'de başlar.
Adam Plocher
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.