POSTing işleminden önce bir önizleme göstermek için REST bitiş noktası


17

Bir REST arka uç ve HTML + JS ön uç tarafından desteklenmektedir yeni bir web uygulaması tasarlıyorum.

Uygulamanın birçok öğesinin durumunda birkaç yan etkisi olan bir varlığı değiştirmek için (PO'yu çağıralım) bir POST yöntemi vardır. POST'un şu şekilde yapıldığını varsayalım :

POST /api/config BODY {config: ....}

Bu nedenle, son kullanıcının nelerin değişeceğini fark edebilmesi için bu değişiklikler yapılmadan önce bir önizleme göstermek istiyorum.

İlk düşündüğüm şey , varlığın yeni durumunun gövdesini göndererek önizleme için bir GET uç noktası yapmak . Bu yoldan:

GET /api/preview/items BODY {config: ....}

Yeni yapılandırmaya sahip öğeler için yeni durum gösterilebilir.

GET /api/preview/sales BODY {config: ....}

Yeni yapılandırma ile satışların yeni durumunu gösterebilir.

Uygulamanın durumunu değiştirmediğim için GET fiilini kullanmak iyi bir fikir gibi görünüyor . Bununla birlikte, GET istekleri ile bir talep gövdesinin kullanılması cesaret kırıcı görünmektedir .

Bu konuda iyi bir uygulama var mı? Diğer seçenek, yapılandırmayı bir yöntemle taslak olarak saklamak ve sonuçları başkalarıyla birlikte görüntülemek olabilir, ancak ek bir adım ve taslakları sunucuda yönetmek zorunda kalmak gerekir:

POST /api/preview/config BODY {config: ....}

GET /api/preview/items?idPreviewConfig=1

Bu yapılandırma tam olarak ne olabilir ve itemsveya sales? İade edilen varlığın temsilini etkiler mi?
Andy

Diyelim ki öğeler ve satışlar yapılandırmada yaptığınız değişikliklerden etkileniyor.
Xtreme Biker

Peki değişiklikler ne anlama geliyor? İade edilen varlık kümesini değiştiriyor mu? Döndürülen yapıyı değiştiriyor mu?
Andy

Aslında POST yapılandırmanıza bağlı olarak itemsve sales(yapı değil) değerlerini değiştirir .
Xtreme Biker

Yapılandırma tam olarak ne kadar büyük? Birkaç yüz kilobayta veya daha fazla büyüyebilir mi?
Andy

Yanıtlar:


27

Bu, HTTP'de yerel bir desteğe sahip olmak için alan adına özgü değildir.

Bunun yerine, aşağıdakilerden birini yapabilirsiniz:

  1. Bir POST /api/config/preview. Sunucu tarafında, uygulama, gerçek yapılandırmayı değiştirmemesi gerektiğini bilecek, ancak gerçek olanı yayınladığınız ile birleştirecek ve neyin değiştiğini gösteren sonucu döndürecektir.

    Daha sonra, kullanıcı sonuçtan memnunsa POST /api/config, önceki talepte olduğu gibi aynı yükü içeren bir performans sergileyecektir . Bu, yapılandırmanın etkin bir şekilde üzerine yazılacaktır.

    Bu yaklaşımın yararı, mevcut API'da herhangi bir değişiklik yapmamanızdır. Önizleme özelliğine ihtiyaç duymayan müşteriler girişleri daha önce olduğu gibi güncelleyebilirler.

    Dezavantajı, vücut büyük olduğunda, sunucuya iki kez gönderilmesi gerektiği anlamına gelir. Bu sizin durumunuzsa, sonraki yaklaşımı kullanabilirsiniz.

  2. Var bir POST /api/config/preparegeçici kayıtlarında gönderildi hatırlar ve iki şey döndüren: (örneğin geçici kayıt kimliği 12345) ve değişikliklerin önizleme.

    Kullanıcı sonuçtan memnunsa POST /api/config/commit/12345, değişiklikleri kesin olarak saklamak için bir performans gösterecektir . Değilse, geçici kayıt bir süre saklanabilir ve daha sonra bir cron işi tarafından atılabilir.

    Avantajı, burada tekrar, orijinali koruyabilirsiniz ve POST /api/configönizleme gerektirmeyen müşteriler kırılmaz.

    Dezavantajları, (1) geçici kayıtların kaldırılması işleminin zor olabileceğidir (bir saatin yeterli olduğunu düşündüren şey nedir? On dakika sonra, belleğiniz biterse? İstemciler, süresi dolan bir kayıt?) ve (2) bir kaydın iki aşamalı olarak sunulması olması gerekenden daha karmaşık olabilir.

  3. Önizleme mantığını istemci tarafına taşıyın.


"Buna devam etme, bana sadece ne olduğunu göster" başlıklı bir başlık göndermeye ne dersiniz? Seninle sorun yoksa cevabı düzenleyeceğim @ArseniMourzenko
marstato

1
@marstato: kişisel olarak, bu kullanım için HTTP başlıklarına özellikle düşkün değilim. Diğer insanlar için mantıklı gelse de, cevabımı düzenlerseniz iyiyim. Ayrıca, başkalarının cevabı almasına izin veren (ve size itibar puanları kazandıracak) kendi cevabınızı da gönderebileceğinizi unutmayın.
Arseni Mourzenko

Sanırım seçenek 1 benim durumum için daha uygun. Böylece önizleme yapılandırmasını POST yaparsınız ve tanımlanan varlıkların her biri için önizleme bitiş noktalarını tanımlamak yerine sonuçta değişiklikler yaparsınız. Mantıklı görünüyor. Tek şey, teknik olarak konuşursak, sunucuda hiçbir değişiklik yapmak için bir POST kullanmanızdır. Seçenek 3 benim durumumda uygulanamaz.
Xtreme Biker

1
@PedroWerneck Bunu genişletebilir misiniz? Bana göre, seçenek 2 başka bir varlığı (taslak yapılandırma) tanımlar ve onlarla etkileşime geçmek için vatansız yollar sağlar.
Andrew, Reinstate Monica'ya

1
@PedroWerneck Bir yapılandırmayı sunucuda saklamak aynı şekilde durum gösterir. Yani uygulama zaten sizin bakış açınızdan durum bilgisi olan ve bu özelliği eklemek için tüm seçenekler de öyle.
jpmc26

10

REST'teki farklı api çağrıları için belirli HTTP fiillerini kullanmanın amacı, mevcut HTTP mekaniği ve beklentilerinden yararlanmaktır.

Bu durumda bir GET kullanmak her ikisine de karşı görünüyor.

C. Müşterinin bir GET'e sahip bir gövde içermesi gerekir mi? beklenmedik

B. Sunucu gövdeye bağlı olarak farklı bir yanıt mı döndürüyor? spec ve önbellek mekaniğini bozar

RESTful sorularla mücadele ediyorsanız, kuralım kendime sormaktır.

"Bu, POST'u her şey için kullanmaktan nasıl daha iyi?"

Anında ve bariz bir fayda yoksa, Just Use POST Stupid (JUPS) stratejisiyle devam edin


Hahaha iyi yakalamak
Xtreme Biker

@Ewan ... bunun pragmatik bir yaklaşım olup olmadığına bakılmaksızın ... her şey için POST kullanıyorsanız, bunun aslında RESTful olmadığı belirtilmelidir.
Allenph

1
POST, tüm yöntemleriniz için uygun seçim olmadığı sürece. Ve uygulayabileceğiniz nesnel bir kural yok gibi değil, sadece bir rehberden biraz daha fazlası hakkında olan öznel yorumlarımızı tartışacağız.
Ewan

6

Sunucuya "bunu devam ettirmeyin, sadece sonuç verirseniz bana ne olacağını gösterin" şeklinde bir başlık gönderebilirsiniz. Örneğin

POST /api/config HTTP/1.1
Host: api.mysite.com
Content-Type: application/json
Persistence-Options: simulate

{
   "config": {
      "key": "value"
   }
}

Sunucunun yanıt verebileceği:

HTTP/1.1 200 OK
Persistence-Options: simulated
Content-Type: application/json

-- preview --

DB'nizle birlikte bir İş Birimi tabanlı O / RM ve / veya isteğe bağlı işlemler kullanırsanız, belirli bir uç nokta üzerinde çalışmak zorunda kalmadan bu işlevselliği tüm uç noktalarınız için kolayca uygulayabilirsiniz: Bu seçenekle bir istek gelirse , işlem / iş birimini işlemek yerine geri alın.



@PeterRader good point, kaldırıldıX-
marstato

Rica ederim. Simülasyon altındaki bir varlığın "simülasyon altında" olarak temsil edilmesi gerektiğini söyleyebilir misiniz?
Peter Rader

Hayır; bu bir simülasyonun amacı, değil mi? Başlık değeri de olabilir, noneancak - benim zevkime göre - POSTyöntemin doğası ile çok fazla çelişir .
marstato

2

Bunu, aramaları yaptığınız gibi ele almanızı öneririm. /api/config/previewYeni bir önizleme OLUŞTURAN bir POST bitiş noktası kurarım. Ardından api/config, geçerli yapılandırmayı düzenlemek veya yalnızca tüm yapılandırmayı değiştirmek isteyip istemediğinize bağlı olarak bir PUT veya PATCH uç noktası ayarlayacağım (muhtemelen önceki durumda yeni oluşturduğunuz önizlemeyi gönderirsiniz).


0

Diğer iyi cevaplarla birlikte, başka bir seçenek de yapılandırmayı yukarıda belirtildiği gibi yüklemek ve bir geri alma işlemine sahip olmak olabilir. Bence, Agile metodolojisi gibi, daha ayrıntılı, tekrarlanabilir ve test edilmiş prosedürler kullanarak değişikliklerden daha az korkmak daha iyidir ve bu, ihtiyacınız olduğunda size bir yedek verir, uygulamaya bağlı olarak riski az ya da hiç azaltmaz. .

Daha sonra, tüm sistemi etkileyen yapılandırma hatalarınız varsa, onu daha aktif olarak ele almak istersiniz ve eğer durum buysa, neden sadece o noktada değişiklikleri bir sunucu veya istemci perspektifinden önizlemek için çaba göstermiyoruz. Her ne kadar bu önizleme özelliğinin geliştirilmesinin daha pahalı olabileceğini görmeme rağmen, kullanım durumlarında takip etmek ve test etmek için kendi ayrı adımları var.


0

RFC6648 yeni X-yapıları kullanımdan kaldırıyor, bu yüzden yeni bir başlık alanı gönderme fikrine karşı oy kullanmalıyım. REST bir mimari tarzıdır, bahsettiğimiz şey RESTful'dır - ancak bu an için bunu görmezden gelelim.

REST Temsilcisi olduğu (ve bir simülasyonun gerçeklikte bir temsili olmadığı) ve Durumsal olduğu (ve bir simülasyon, işlenene kadar bir durum olmadığı için), bir simülasyon kapsamı gibi yeni bir kapsamımız olmalıdır. Ancak simülasyon yerine emülasyon olarak adlandırmalıyız çünkü simülasyon simülasyon sürecini içerir, ancak durumsal bir durumumuz, bir simülasyonun ideal bir çözümü: bir emülasyonumuz anlamına gelir. URL'ye öykünme dememiz gerekiyor. Bu da iyi bir çözüm olabilir:

GET  /api/emulation - 200 OK {first:1, last:123}
POST /api/emulation/124 - 200 OK
GET  /api/emulation/124/config - 200 OK {config:{tax:8}}
PUT  /api/emulation/124/config {config:{tax:16}} - 200 OK {config:{tax:16}}
GET  /api/emulation/124/items - 200 OK [first:1, last: 3000]
GET  /api/emulation/124/items/1 - 200 OK {price:1.79, name:'Cup'}
--- show emulation ---
--- commit emulation ---
PUT /api/config {config:{tax:16}}
DELETE /api/emulation/124 - 200 OK

Başka bir yaklaşım daha var ... HTML / JavaScript istemcisinden gelen çok sayıda istekte bulunmanın , aynı anda yaklaşık 17 istek sınırına ulaşan çok fazla istek üretebileceğini fark edebilirsiniz ( bu sayfaya bir göz atın ). REST kullanımını değiştirebilir ve topal nesne durumları yerine zengin kullanıcıya özgü sayfa durumları gönderebilirsiniz. Misal:

GET /user/123/config - 200 OK {user:'Tim', date:3298347239847, currentItem:123, 
                  roles:['Admin','Customer'], config:{tax:16}, unsavedChanges:true, ...}

Saygılarımla

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.