POST'tan sonra içeriğin REST tarafından döndürülmesi uygun mu?


89

RESTlet kullanıyorum ve bir kaynak oluşturdum. POST'u geçersiz kılarak ele alıyorum acceptRepresentation.

İstemci bana bazı veriler göndermeli, sonra bunu DB'ye depolamalı, yanıtı 201 (SUCCESS_CREATED) olarak ayarlamalı ve istemciye bazı verileri döndürmem gerekiyor, ancak acceptRepresentationis türünü döndürmeliyim void.

Benim durumumda, müşterinin bu kaynağa erişebilmesi için bir tanımlayıcı iade etmem gerekiyor.

Örneğin, URL ile bir kaynağım varsa /resourceve müşteri POST isteği gönderirse, DB'ye yeni bir satır eklerim ve adresi olmalıdır /resource/{id}. Ben göndermek gerekir {id}.

Yanlış bir şey mi yapıyorum? REST ilkeleri POST'tan sonra bir şey döndürmeye izin veriyor mu? Cevabınız evet ise, nasıl yapabilirim ve hayır ise bu durumu nasıl çözebilirim?


Kabul gövdesini kabul et () içinden nasıl ayarlayacağınızı öğrenmek için Thom'un cevabına bakın.
Avi Keten

Yanıtlar:


97

REST sadece tek tip arayüze uymanız gerektiğini söylüyor. Başka bir deyişle, HTTP özelliklerine göre POST'un yapması gereken şeyi yapmanız gerektiğini söylüyor . İşte bu spesifikasyondan alakalı olan alıntı,

Kaynak sunucuda bir kaynak yaratılmışsa, yanıt 201 (Oluşturuldu) OLMALIDIR ve talebin durumunu açıklayan ve yeni kaynağa atıfta bulunan bir varlık ve bir Konum başlığı (bkz. Bölüm 14.30).

Buradan da görebileceğiniz gibi, yeni oluşturulan kaynağın nerede olduğunu müşteriye belirtebileceğiniz iki yeriniz var. Konum başlığı, yeni kaynağa işaret eden bir URL'ye sahip olmalıdır ve ayrıca ayrıntılarla birlikte bir varlık da döndürebilirsiniz.

Kabul etmekRepresentation () ile postayı () geçersiz kılmak arasındaki farkın ne olduğundan emin değilim, ancak bu örnek bir POST'tan nasıl yanıt döndürüleceğini gösteriyor.


2
@ del-boy: Kabul gövdesini kabul etme () içinden nasıl ayarlayacağınıza ilişkin Thom'un cevabına bakın.
Avi Keten

1
HTTP spesifikasyon alıntı bir yanıtı yasaklamaz, eğer Bölüm 6'ya bakarsanız, Request and Response messages MAY transfer an entity if not otherwise restricted by the request method or response status code. An entity consists of entity-header fields and an entity-body, although some responses will only include the entity-headers.
şunun

@MikeF Bir yanıt gövdesine izin verilmediğini anlamaya çalıştım. Spesifikasyonun özellikle alıntı yaptığım kısmı "ve bir varlık içerir" diyor. Metnimde daha net olmalıydım.
Darrel Miller

16

Yanıtın gövdesinde herhangi bir şey göndermekten vazgeçerim. Sadece Location: öğesini yeni oluşturulan kaynağın (tam) URL'sine ayarlayın.

Açıklamanız, bunun tam olarak sizin semantik olduğunu gösteriyor:

  1. Oluşturmak için bir şey gönderin
  2. İki şeyi bilecek kadar cevap verin:
    1. Yaratılışın gerçekleştiğini (201)
    2. Yeni şey nerede bulunur (Konum başlığı)

Başka herhangi bir şey gereksizdir.


Wikipedia her zaman iyi bir kaynak değil , aynı zamanda "[...] Yeni oluşturulan bir kaynağın konumu hakkında bilgi sağlamak için. Bu durumda, Konum başlığı 201 veya 202 HTTP durum koduyla gönderilmelidir. . "
Arjan

1
POST, bir veya daha fazla kaynak oluşturan mantığı yürütebilir. İşlemin sonucuna müşteri tarafından ihtiyaç duyulabilir. Dolayısıyla, yanıtta döndürmek, API'ye bir veya daha fazla GET çağrısı yapma ihtiyacını ortadan kaldırır. POST yöntemi tarafından oluşturulan / değiştirilen veriler, istemci için gereksiz olmayabilir (ve çoğu zaman değildir).
Paulo Merson

10

İki farklı soru:

REST uygulama kalıbı, POST'ta veri döndürmeyi destekliyor mu?

REST'in bunu açıkça reddettiğini sanmıyorum, ancak tercih edilen tedavi Darrel'in cevabında açıklanıyor.

RESTlet çerçevesi bir POST'ta verilerin geri döndürülmesine izin veriyor mu?

Evet, void döndürmesine rağmen, Resource'u genişleten bir sınıfta, getResponse () yöntemi aracılığıyla Response nesnesine tam erişime sahipsiniz. Böylece getResponse (). SetEntity () 'yi istediğiniz verilerle çağırabilirsiniz.


6

İstenilen formatta çıktı alın. Bu olabilir:

<success>
    <id>5483</id>
</success>

Veya:

{ "type": "success", "id": 5483 }

Genelde ne yaptığına bağlı. Verileri beklemiyorlarsa, sadece görmezden gelmeleri gerekir, ancak verileri doğru şekilde kullanmak isteyen herhangi bir müşteri bunu yapabilmelidir.


Tamam, iki olası formatım var (html ve xml). İstenen biçim türünü nasıl işleyeceğimi biliyorum, ancak yanıta nasıl veri ekleyeceğimi bilmiyorum. Temsil yöntemi, Temsili döndürür, bu yüzden sadece istediğim şeyi döndürürüm, ancak kabul etme, geçersiz bir yöntemdir, bu yüzden herhangi bir veri döndüremiyorum ...
del-boy

1

Bir Konum yeniden yönlendirmesi yerine bir varlık gövdesiyle oluşturuldu olarak yanıt verirseniz, yanıtta temsil edilen kaynağa işaret eden bir İçerik-Konum başlığı eklemek iyi bir fikirdir.

Bu, bir müşterinin (haklı olarak) yanıt varlığının yaratılan kaynağın değil, 'yaratanın' yeni bir durumunu temsil ettiğini varsayabileceği olası karışıklığı önleyecektir.

> POST /collection
> ..new item..

< 201 Created
< Location: /collection/1354
< Content-Location: /collection/1354
< <div class="item">This is the new item that was created</div>

3
Bence İçerik-Konum farklı bir amaç için. HTTP spesifikasyonu, İçerik Yerinin POST ve PUT için tanımlanmadığını söylüyor. Konum başlığı bir 201-Create ile kullanılır. Bir Konuma dönmek otomatik olarak bir yönlendirme yapmaz, bunun için bir 3XX yanıt koduna ihtiyacınız vardır.
Darrel Miller

1
Konum başlığı, oluşturulan kaynağın nerede bulunduğunu belirtmek için kullanılır (201 yanıtında); eşlik ettiği yanıtın kuruluş gövdesi ile ilgili değildir. Demek istediğim şuydu - oluşturulan kaynağı 201 yanıtının kendisine dahil etmek istiyorsanız (istemciyi başka bir URI'ye yönlendirmek / yeniden yönlendirmek yerine), o zaman bir içerik-konum başlığı iyi bir fikir olacaktır. Bu muhtemelen kuralları biraz esnetiyor, ancak yeni kaynağın durumunu istemciye iletmek için başka bir istek / yanıt döngüsü gerektirmekten daha etkilidir.
Mike

Bana mantıklı geliyor. Daha önce Content-Location başlığını hiç kullanmadım.
Darrel Miller

istemci tarayıcısı olan bir insan ise, Konum başlığı ile 201 döndürmenin bir anlamı yoktur. Kullanıcı onunla ne yapacağını bilemeyecek. müşteri bir robot ise, onunla nasıl başa çıkılacağını bilerek programlanabilir - Konumda bir GET takibi gibi.
tartışmasız

3
@irreputable: REST'in API'leri tasarlamak için olduğuna inanıyorum, burada A, render etmek için biraz HTML arayan bir Kullanıcı Aracısı anlamına gelmiyor.
Hermes
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.