HTML'i bir JSON API'sinden döndürmek uygun mudur?


25

Mevcut projemde yalnızca JSON'u desteklediği belgelenen yeni oluşturulan RESTful API'lerin tüketimini içeren bir hizmetin uygulanmasından sorumluyum.

Müşteri sürekli 'application / json' kabul başlığını ve 'application / json' içerik türünü talep eder. Bununla birlikte, bazı bitiş noktaları bir HTML gövdesi bile olsa bir HTML içerik türüne bir yanıt gönderir. Bana göre bu açıkça yanlış bir yaklaşım ve hiçbir zaman haklı gösterilemez.

Proje boyunca bu aynı uygulama iki farklı satıcı ve iki farklı hizmet arasında uygulanmıştır. Hizmetlerin neden değiştirilmesi gerektiğine karar vermek zorunda olduğumu kendim buldum. Satıcılar müşterinin bununla başa çıkması gerektiğini ve hatta REST tercih kitaplığımın sorgulandığını (RestEasy) sorguladı çünkü varsayılan olarak 'kutusundan' çıkar.

Bu büyük bir hayal kırıklığı noktası olmuştur. Argümanımı desteklemek için pek çok referans bulamıyorum, bunun sebebi, mesele o kadar açık ki olduğu gerçeğidir.

Asıl soru, bir şey eksik mi? Bu konuda bilgiçlik mi ediyorum? Bu senaryoda içerik türü bir uygulama / json içermeyen bir JSON API olması uygun mudur? Referanslar memnuniyetle karşılanacaktır. Bu durumu ticari açıdan nasıl çözersiniz?


1
Bağlam türüne göre içerik tipi HTTP başlığını mı kastediyorsunuz?
Marjan Venema

Evet, HTTP içerik tipi başlığına atıfta bulunuyorum. Düzenlenen.
phillip.darley

Eh, en azından bir HTML REST API'si olduğunda "JSON REST API" dememeliler.
Bergi

Yanıtlar:


28

acceptBelirli bir ortam türü isteyen bir başlık gönderirken , sunucu başka bir şey geri göndermemeli ve kesinlikle 200 OK durum kodu ile göndermemelidir.

Restpatterns.org'dan :

Kabul et başlık alanı yoksa, istemcinin tüm medya türlerini kabul ettiği varsayılır. Bir Kabul başlığı alanı mevcutsa ve sunucu birleşik Kabul alanı değerine göre kabul edilebilir bir yanıt gönderemiyorsa, sunucu bir 406 (kabul edilemez) yanıtı göndermelidir.

(Vurgu madeni)

Restpatterns.org bunu asıl HTTP standardından alır: Başlık alanı tanımları - Kabul et

Kısacası: bilgiçlikçi olmuyorsunuz. Servisler, kabul başlığı özel olarak geri dönmelerini söylerken HTML döndürüyorlarsa HTTP standardını takip etmiyorlar application/json.


1
+1. Bu cevaba katılıyorum, ancak ne yazık ki kelime shoulddefalarca HTTP spesifikasyonlarında kullanılıyor. Bu kelimelerin değişmesi için çevrimiçi bir dilekçe başlatmalıyız must.
Tepki

3
@MarjanVenema "olmalıdır" dır, çünkü aynı rfc'den 10. bölümde, bir not var: "HTTP / 1.1 sunucularının, talepte gönderilen kabul başlıklarına göre kabul edilemeyecek yanıtları döndürmesine izin verilir. Bazı durumlarda, bu bile 406 yanıt göndererek tercih edilmek istenebilir. "
imel96

1
Eğer bir müşteri gerçekten bir JSON temsiline sahip olmayan bir kaynak isterse , o zaman ne kadar JSON istediği önemli değil, belki de kesin olan başka bir şey almaktan daha iyidirler; 406 almanız garanti edilmez. Önemli olan, sunucunun yanıtın içerik türünün gerçekte ne olduğunu açıklamasıdır.
Donal Fellows

6
@DonalFellows: Hayır, gerçekte ne olduğu konusunda bilgilendirilmeleri daha iyi olur. Sunucu sadece uygun olduğunu düşündüğü bir şeyi geri göndermemeli, aynı zamanda standartta belirtildiği gibi 406 kabul edilemez bir yanıt göndermelidir. İstemci özel olarak bir ortam türü istediğinde ve herhangi bir geri dönüş belirtmediğinde, muhtemelen başka bir ortam türünü işlemenin hiçbir yolu olmadığını unutmayın.
Marjan Venema

2
@ imel96: İnternetin hiçbir zaman katı olmadığı gerçeği, çeşitli tarayıcıları desteklemeye çalışırken zorluk çeken sorunlara ve şu anda çok fazla olduğu için geçerli olmayan html ile geriye dönük olarak uyumlu kalmaya zorlanan sunuculara tam olarak neden olan şey. (ve ne yazık ki hala yaratılıyor).
Marjan Venema

9

"RESTful JSON API" ile neyi kastediyorsunuz - Bence buradaki ilk mesele kavramları karıştırmanız (ya da belki de "tedarikçilerinizdeki teknik meslektaşlarınız ile aranızdaki biri").

Bir RESTful API (hiç konuşmuyor olsanız da gerçekten 1. seviyede ya da 3. veya daha yüksek seviyelerde bir şey varsa http://martinfowler.com/articles/richardsonMaturityModel.html ) API ile ilgili değil gönderilen veya gelen içeriğin biçimi. Protokoller ya da nakliye mekanizmaları hakkında bile değil ...

Benzer şekilde, bir JSON API, JSON'un veri formatı olarak kullanımını destekleyen bir API'dir - dinlendirici olabilir veya olmayabilir, HTTP kullanarak uygulanabilir veya olmayabilir ve (ve bu da kilit noktadır) JSON'u destekleyebilir veya desteklemeyebilir. münhasıran.

Bir iyi üzerinden HTTP çalışan API (onun bağlamda baştan HTTP maruz bir API bahsediyoruz olduğunu varsaymak makul) çeşitli biçimlerde içinde istek içeriğe sizi izin vermelidir ve bu biçimlerin (ve muhtemelen olmalı) HTML dahil yanı sıra edebilirsiniz JSON ve XML. Niye ya? API'yi öğrenmeyi çok daha kolay hale getirirdi, kavramsal olarak herhangi bir amaç için anında bir tarayıcı tabanlı UX sağlar ...

İlginç bir soru, çeşitli içerik formatlarını destekleyen API'mın müşteriye hangi formatta beklediğini söylemeden çağrılırsa, sonra hangi formatta dönmesi gerekir? Bu, dini bir argümana yönelir - ancak HTML, sağlayıcıya faydalı bilgiler ekleme seçeneği sunar ("içeriğin üstbilgisini kabul etmeyi unutma" gibi).

Soruyu bir API'ye cevaplamak için, dinlendirici ve json'u destekleyen biri, istenen içerik buysa, kesinlikle HTML'yi döndürebilmelidir.


1
Her iki noktanı da alıyorum ve sorumu buna göre düzenledim. Hizmetin RESTful olduğu gerçeği önemli değildir ve müşterinin her isteğinde 'uygulama / json' kabul ettiğini ayrıntılı olarak açıkladım.
phillip.darley 10:13

"RESTful JSON API" nin çok açık bir anlamı olduğunu söyleyebilirim.
gnasher729

1
Ben öğretmenlerim nedenini "varsaymak asla" anlaşılan iyi bir programcı olmak önemli bir parçası oldu emin içine çaba bir çok şey koymak söyleyebilirim
Murph

5

Müşteri sürekli 'application / json' kabul başlığını ve 'application / json' içerik türünü talep eder.

Evet, yapılacak doğru şey bu, ancak satıcının umurunda olduğu anlamına gelmez. Hayal kırıklığınızı tamamen anlıyorum, çünkü ayrıca bir JSON hizmetinin her zaman bir JSON yanıtı vermesi gerektiğini düşünüyorum ama durumun böyle olmadığı birçok örnek var.

Proje boyunca bu aynı uygulama iki farklı satıcı ve iki farklı hizmet arasında uygulanmıştır. Hizmetlerin neden değiştirilmesi gerektiğine karar vermek zorunda olduğumu kendim buldum. Satıcılar müşterinin bununla başa çıkması gerektiğini ve hatta REST tercih kitaplığımın sorgulandığını (RestEasy) sorguladı çünkü varsayılan olarak 'kutusundan' çıkar.

Satıcı ile aynı fikirdeyim. Bu onların servisi ve onu kullanmak için özel durumları açıkça belgelemiş oldukları sürece, gerçekten değiştirdiklerini empoze edemezsiniz. Geliştiricilerin API'lerini benimsemeleri yavaş olduğundan ve geliştiricilerin ihtiyaç duyduklarını dinlerlerse değiştirecekleri için bir dezavantajdır, ancak ne yazık ki standartlara uymaları gerektiği konusunda hiçbir kural yoktur.

Sorun şu ki bir şey eksik mi?

İstek başlıkları, diğer uçta doğru şekilde kesilmediği sürece hiçbir şey ifade etmez. PHP kullanarak bir web API geliştirirsem, o zaman istek başlıklarını cehenneme çeviririm. Ne istersem ona cevap verebilirim. Oysaki, IIS'de C # ile yapılandırılmış bir hizmet, istek başlıklarını, türlerini ve yanıt türünü kullanmada çok daha kolay kullanım sağlar. Satıcının API'yi oluşturmak için kullandığı araçlarla ilgisi vardır.

Bu konuda bilgiçlik mi yapıyorum?

Evet ve Hayır. Bunu geçemeyen geliştirici arkadaşlarım var. Sorun çözüldüler ve API çalışmasını beklediği şekilde çalışana kadar diğer görevlere devam edemezlerdi. Şimdi bu bilgiçlik yapıyor.

Bu bir problem çünkü satıcı görevlerinizi tamamlamak için "daha fazla iş" yarattı. Bu konuda herkes hayal kırıklığına uğrayacaktı. Ben olacağımı biliyorum.

Bu senaryoda içerik türü bir uygulama / json içermeyen bir JSON API olması uygun mudur?

Kesinlikle, ama bu iyi bir uygulama değil.

Bir istemci, sunucuya yalnızca bir bağlamın türünün ne olduğunu söyleyebilir request. İçin bir içerik türü uygulama yeteneği yoktur response. İstemci, sunucuya yalnızca acceptolası içerik türleri topluluğu olacağını bildirir .

Başlık Alanı Tanımları

Kabul etme isteği-başlık alanı, yanıt için kabul edilebilir olan belirli ortam türlerini belirtmek için kullanılabilir. Kabul edilen başlıklar, isteğin, hat içi bir görüntü için yapılan bir talepte olduğu gibi, istenen küçük bir grup kümeyle özellikle sınırlı olduğunu belirtmek için kullanılabilir.

Bir müşterinin bir resim talep etmesi mümkündür image/jpeg, ancak sunucu , resmin bulunup bulunmadığı ile ilgili text/htmlbir durum kodu ve yanıt verir 404. Sunucular da yanlış cevap verebilir. Sayfada bulunmayan dosyalar için yanıt veren pek çok Wordpress web sitesi text/htmlve durum kodu var 200.

Şimdi bu sunucunun tüm BAD uygulamasıdır. Söylemeye çalıştığım şey, bu kesinlikle mümkün ve sık sık oluyor. İnsanlar bunları yapılandırırken ne yaptıklarını bilmiyorlar.

Referanslar memnuniyetle karşılanacaktır. Bu durumu ticari açıdan nasıl çözersiniz?

Bu soruna birkaç projede rastladım. Sen postJSON verilerini sunucuya ve o bir JSON veya HTML yanıtı verir.

Yanıtta hangi tip olduğunu bilmek gerçekten önemli bir şey değil. İlk karakter ise {veya [JSON varsayalım. Eğer öyleyse <, HTML varsayabilirsin. Geçmişte böyle idare ettim. Bazen API'yi yazan programcı, HTTP başlıkları hakkında her şeyi bilir. Her şey text/htmlcevap olarak geri dönüyor . Şanslıysanız, Apache varsayılan olarak yapılandırılmış ve text/plainbazen yardımcı olabilir.

Bu sorunlar var ve gelecekte de var olmaya devam edecekler. Sunucudan sunucuya iletişim, bugüne kadar düzenlenmemiş bir etkinliktir. Kötü HTTP yanıtları veren bir sunucu için bir satıcıyı sendikadan atacak bir yönetim organı yoktur.


Bu, @Marjan Venema'nın cevabı ile aynı çizgidedir, ancak yükselteceğiniz bir diğer önemli nokta bu davranışın belgelendirilmesidir. Hayal kırıklığımı eklemek için satıcı bu davranışı belgelendirmedi. İçerik tipi oturum durumuna bağlı olarak değişir, ancak yalnızca JSON yanıtı belgelenir.
phillip.darley 11:13
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.