Fiiller olmadan REST URL'leri nasıl oluşturulur?


283

Huzurlu URL'lerin nasıl tasarlanacağını belirlemeye çalışıyorum. Ben URL'leri isim ile kullanmak ve fiiller değil bunu nasıl yapacağımı anlamıyorum huzurlu bir yaklaşım için.

Finansal hesap makinesi uygulamak için bir hizmet oluşturuyoruz. Hesap makinesi, bir CSV dosyası aracılığıyla yükleyeceğimiz bir grup parametreyi alır. Kullanım durumları şunları içerir:

  1. Yeni parametreler yükle
  2. En son parametreleri edinin
  3. Belirli bir iş tarihi için parametreler alma
  4. Bir parametre kümesini aktif hale getirme
  5. Bir dizi parametreyi doğrulayın

Ben dinlendirici bir yaklaşım aşağıdaki tip URL'lere sahip olacak toplamak:

/parameters
/parameters/12-23-2009

İlk üç kullanım durumunu aşağıdakilerle elde edebilirsiniz:

  1. Posta isteğine parametre dosyasını eklediğiniz POST
  2. İlk URL'yi ALIN
  3. İkinci URL'yi AL

Fakat 4. ve 5. kullanım durumunu fiil olmadan nasıl yaparsınız? Şunun gibi URL'lere ihtiyacınız olmaz mı:

/parameters/ID/activate
/parameters/ID/validate

??


3
Kısmi güncelleme için POST yerine PATCH'yi tercih ederim.
user2016971

Yanıtlar:


71

Belki şöyle bir şey:

PUT /parameters/activation HTTP/1.1
Content-Type: application/json; encoding=UTF-8
Content-Length: 18

{ "active": true }

1
POSTHer istek gönderdiğinizde parametreleri doğrulamak gibi bir "yordam" gerçekleştirmeniz gerekiyorsa sorun olmaz. Ancak kaynağın (uygulama) durumunu değiştirdiğinizde, yeni bir kaynak oluşturmaz veya bir işlem isteği yayınlamaz, gerçekte mevcut kaynağı güncelleştirirsiniz .
Andrey Vlasovskikh

19
PUT, yeni bir kaynak oluşturmak veya belirli bir URL'ye yeni bir kaynak yerleştirmek (kısmen değil) içindir. PUT'un bu duruma nasıl uyduğunu göremiyorum.
Breton

30
Aslında POSTvs PUTtam olarak benzemese insertvs update. PUTverilen yola karşılık gelen kaynağı günceller veya verilen yola karşılık gelen yeni bir kaynak oluşturur. POSTbir yerde yeni bir kaynak yaratır. Örneğin PUT /blog/posts/3/comments/5, uygun yorumu güncellerken POST /blog/posts/3/commentsyeni bir commentkaynak oluşturur (ve yanıtta yeni kaynağın yolunu döndürmelidir).
yfeldblum

23
@Justice @Breton Daha önemli fark PUT, idempotent POSTolmamasına rağmen. Genellikle, sonuç olarak verdiğiniz şeyler üzerinde olabildiğince çok kısıtlama koymalısınız. Yapışma PUT, hizmet istemcisine daha fazla bilgi verir.
Andrey Vlasovskikh

3
Kaynak / parametreler / durum da olabilir ve isteğin gövdesi yalnızca "etkin" olabilirdi. Bu şekilde, bir şekilde belirli bir URL'ye tamamen yeni bir kaynak yerleştiriyorsunuz.
Carlos Aguayo

991

İyi URI tasarımı için genel ilkeler:

  • Etmeyin alter durumuna sorgu parametreleri kullanmak
  • Yapma bunu yardımcı olabilir harfleri karışık yolları kullanacak; küçük harf en iyisidir
  • Yapmayın sizin URI'ler (.php, .py, .pl, vs.) uygulanması özgü uzantılarını kullanmak
  • Do not düşmek RPC sizin URI'ları ile
  • Do mümkün olduğunca URI uzayınızı sınırlamak
  • Do kısa tutmak yol parçaları
  • İkisini de tercih edin /resourceveya /resource/; kullanmadığınızdan 301 yönlendirmeleri oluşturun
  • Do bir kaynağın alt seçimi için kullanılması sorgu parametreleri; ör. sayfalama, arama sorguları
  • Do bir HTTP başlık veya vücutta olmalıdır URI dışına hareket şeyler

(Not: "RESTful URI design" demedim; URI'ler aslında REST'te opaktır.)

HTTP yöntemi seçimi için genel ilkeler:

  • GET'i hiçbir zaman durumu değiştirmek için kullanmayın; Googlebot'un gününüzü mahvetmesini sağlamanın harika bir yolu
  • Do bütün bir kaynak güncelleme sürece PUT kullanmak
  • Yapmayın ayrıca meşru aynı URI bir GET yapabilirsiniz sürece PUT kullanmak
  • Etmeyin uzun ömürlü olan bilgileri almak için POST kullanabilir veya bu cache makul bir yaklaşım olabilir
  • Yapmayın olmayan bir işlemi gerçekleştirmek İdempotent PUT ile
  • Do mümkün olduğunca için kullanılması GET
  • Do Şüphe durumunda, PUT tercih edilerek kullanılması POST
  • Do RPC-gibi hissediyor şey yapmak zorunda olduğunda kullanılması POST
  • Daha büyük veya hiyerarşik kaynak sınıfları için PUT komutunu kullanın
  • Do kaldır kaynaklara POST tercih için DELETE kullanımı
  • Do hesaplamaları gibi şeyler için kullanılması GET, girişinizi büyük olmadığı sürece, bu durumda kullanım POST içinde

HTTP ile web hizmeti tasarımının genel ilkeleri:

  • Do not bir başlığında olması gereken bir yanıt metninde meta koymak
  • Yapmayın bunu önemli ek yük yaratacak dahil olmadıkça ayrı bir kaynak meta koymak
  • Do uygun durum kodu kullanabilirsiniz
    • 201 Createdbir kaynak oluşturduktan sonra; kaynak , yanıtın gönderildiği sırada bulunmalıdır
    • 202 Accepted bir işlemi başarıyla gerçekleştirdikten veya eşzamansız olarak bir kaynak oluşturduktan sonra
    • 400 Bad Requestbirisi veri üzerinde açıkça sahte olan bir işlem yaptığında; uygulamanız için bu bir doğrulama hatası olabilir; yakalanmamış istisnalar için genellikle 500 rezerv
    • 401 Unauthorizedbirisi gerekli bir Authorizationüstbilgi sağlamadan API'nıza eriştiğinde veya içindeki kimlik bilgileri Authorizationgeçersiz olduğunda; Authorizationüstbilgiden kimlik bilgileri beklemiyorsanız bu yanıt kodunu kullanmayın .
    • 403 Forbidden birisi API'nıza kötü amaçlı olabilecek bir şekilde eriştiğinde veya yetkilendirilmediğinde
    • 405 Method Not Allowed birisi POST kullandığında, PUT vb.
    • 413 Request Entity Too Large birisi size kabul edilemeyecek kadar büyük bir dosya göndermeye çalıştığında
    • 418 I'm a teapot bir çaydanlıkla kahve demeye çalışırken
  • Do kullanım önbelleğe alma üst zaman yapabilirsiniz
    • ETag bir kaynağı karma değerine kolayca azaltabildiğinizde üstbilgiler iyidir
    • Last-Modified size kaynakların güncellendiği zaman damgasını tutmanın iyi bir fikir olduğunu belirtmelidir.
    • Cache-Controlve Expiresmantıklı değerler verilmelidir
  • Do bir istek başlıkları önbelleğe onurlandırmak için her şeyi ( If-None-Modified, If-Modified-Since)
  • Do kullanım yönlendirmeleri onlar mantıklı zaman, ama bunlar bir web hizmeti için nadir olmalıdır

Özel sorunuzla ilgili olarak # 4 ve # 5 için POST kullanılmalıdır. Bu işlemler yukarıdaki "RPC benzeri" yönergelerine tabidir. # 5 için POST'un mutlaka kullanmak zorunda olmadığını unutmayın Content-Type: application/x-www-form-urlencoded. Bu bir JSON veya CSV yükü kadar kolay olabilir.


11
413 size gönderilen isteklerin boyutu için tasarlanmıştır, böylece genellikle 411 ile birlikte size veri konserleri gönderen birini kibarca reddedebilirsiniz, böylece insanları size ne kadar gönderildiğini söylemeye zorlarsınız. 413'e karşı verilen örnek için, bence 400 daha uygun bir yanıt olacaktır.
Garry Shutler

5
+1, çünkü bu harika bir kaynak. Ancak, bu genel bir kaynaktır ve doğrudan soruyu cevaplamaz. Bu ideal olarak belirli bir yanıtı olan ek bir paragraf içermelidir.
Samuel Neff

@GarryShutler İyi yakaladın, kesinlikle haklısın. Düzenleme için teşekkürler.
Bob Aman

1
Evet, PUT'u yalnızca tüm nesnenin üzerine yazdığınız durumlarda kullanırsınız . Ancak, bir kaynağın kısmi güncellenmesi durumunda PATCH veya POST'un makul olduğunu iddia ediyorum . PATCH , işlemin ne yapacağına göre daha açıktır, ancak tüm istemciler bir PATCH isteği bile gönderemediğinden , bunun yerine bir POST'a izin vermek tamamen uygundur ve hatta bir POST eğer hep son çare olarak izin verilmelidir YAMA kullanılır.
Bob Aman

1
409 hataları için +1. 400 hatası, yeterli istemci tarafı doğrulamasıyla çözülebilecek bir şeydir. 409, isteğin kendisinin kabul edilebilir ve tutarlı olduğunu açıklar, ancak sunucu durumunun bazı yönleriyle çakışır (genellikle eşzamanlılık denetimleri, ancak teorik olarak girdi olmayan herhangi bir kısıtlama).
claytond

18

Ne zaman yeni bir fiile ihtiyacınız varsa, o fiili bunun yerine bir isme dönüştürmeyi düşünün. Örneğin, "etkinleştir" i "etkinleştirme" ye, "doğrula" yı "geçerlilik" e çevirin.

Ancak yazdıklarınızdan itibaren uygulamanızın çok daha büyük sorunları olduğunu söyleyebilirim.

'Parametre' adı verilen bir kaynak önerildiğinde, her proje ekibi üyesinin zihninde kırmızı bayraklar göndermelidir. 'parametre' herhangi bir kaynağa tam anlamıyla uygulanabilir; yeterince spesifik değil.

Bir 'parametre' tam olarak neyi temsil eder? Muhtemelen, her biri ayrı bir kaynağa sahip olması gereken bir dizi farklı şey.

Bunu yapmanın başka bir yolu - uygulamanızı son kullanıcılarla (programlama hakkında çok az şey bilenler) tartıştığınızda, tekrar tekrar kullandıkları kelimeler nelerdir?

Bunlar uygulamanızı tasarlamanız gereken kelimelerdir.

Potansiyel kullanıcılarla bu dönüşümü henüz yapmadıysanız - şu anda her şeyi durdurun ve yapana kadar başka bir kod satırı yazmayın! Ancak o zaman ekibinizin neyin inşa edilmesi gerektiği hakkında bir fikri olacaktır.

Finansal yazılımlar hakkında hiçbir şey bilmiyorum, ama tahmin etsem kaynakların bir kısmının "Rapor", "Ödeme", "Transfer" ve "Para Birimi" gibi isimlerle gelebileceğini söyleyebilirim.

Yazılım tasarım sürecinin bu kısmında birçok iyi kitap bulunmaktadır. Tavsiye edebileceğim iki alan, Etki Alanına Dayalı Tasarım ve Analiz Kalıplarıdır .


1
Bu gerçekten iyi bir nokta. Resmi mantık ve akıl yürütme için aklınızdaysa kaçırmak kolaydır. X'in diğer parçalarla birlikte geçerli bir şekilde uyduğu sürece ne olduğu önemli değil. İnsan faktörleri kaybolur.
Breton

1
Bazen kelimeleri "aktivatör" veya "validator" gibi bir "işleme kaynağı" na dönüştürmeyi faydalı buluyorum. RFC 2616 uyarınca POST "bir veri işleme sürecine bir veri bloğu ... sağlamak" için kullanılabilir
Darrel Miller

Anladım. Bu durumda, kullanıcılar verilere "parametreler" (veya "risk parametreleri" veya benzer bir şey) derler. Parametre listesi birçok farklı ayar türü içerir, ancak parametreler her zaman bir bütün olarak (bir CSV dosyasında) yüklenir.
Marcus Leon

@Marcus - çok sıradışı bir durum gibi geliyor. Belki de uygulamanızın ne yaptığını daha ayrıntılı bir şekilde açıkladıysanız, kaynakları tanımlamak için daha iyi öneriler sunabiliriz.
Zengin Apodaca

1
"Uygulamanızı son kullanıcılarla tartıştığınızda, tekrar tekrar kullandıkları kelimeler nelerdir?" ... ya hepsi fiilse? XD
Amalgovinus

11

URL'lerinizin tasarımının, uygulamanızın RESTful olup olmadığıyla hiçbir ilgisi yoktur. Bu nedenle "RESTful URLs" ifadesi saçmalıktır.

Bence REST'in gerçekte ne olduğunu biraz daha okumalısınız. REST, URL'lere opak davranır ve bu nedenle içlerinde ne olduğunu, fiil veya isim olup olmadığını bilmiyor. URL'lerinizi yine de tasarlamak isteyebilirsiniz, ancak bu REST ile değil kullanıcı arayüzüyle ilgilidir.

Bununla birlikte, sorunuza geçelim: Son iki vaka RESTful değil ve herhangi bir dinlendirici şemaya uymuyor. Bunlar RPC diyebileceğiniz şeydir. REST konusunda ciddiyseniz, başvurunuzun sıfırdan nasıl çalıştığını yeniden düşünmeniz gerekir. Ya bu ya REST'i bırakın ve uygulamanızı bir RPC uygulaması olarak yapın.

Hrmmm olmayabilir.

Buradaki fikir, her şeyi bir kaynak olarak ele almanız gerektiğidir, bu nedenle bir dizi parametre buna başvurabileceğiniz bir URL'ye sahip olduğunda şunları eklersiniz:

GET [parametersurl]/validationresults

POST [paramatersurl]
body: {command:"activate"}

Ama yine de, bu etkinleştirme REST değil RPC'dir.


Burada ilginç bir noktaya değindin. Böyle bir şey için RESTful yaklaşımının nasıl olacağını biraz daha ayrıntılandırabilir misiniz?
22'de poezn

Buradaki yanıtları okumak için biraz zaman harcadım ve bence adalet bir şeye bağlı olabilir. parametre nesnenizin bireysel özelliklerini tek tek kaynaklar olarak modeller ve söz konusu kaynağın söz konusu özelliğinin içeriğini değiştirmek için PUT fiilini kullanır. Bu, her nesnenin durumunu bir kaynak koleksiyonu olarak modellemek ve durumu kaynağı yerleştirmek veya kaldırmak veya değiştirmek olarak değiştirmektir. Doğrulama gelince- Sadece cevabımda yukarıdaki gibi, parametrelerin geçerli olup olmadığını sihirli bir şekilde bildiren bir kaynağa ihtiyacınız var. Yan etkisi olmadığı sürece bu iyi olur.
Breton

Tabii ki, "Etkinleştir" in yaptığı tek bir özelliği true olarak ayarlamaktır. Başka bir şey yapması gerekiyorsa, yine de RESTful değil ve RESTfully nasıl modelleyeceğinizden emin değilim.
Breton

Son iki vakanın RESTful olmadığını söyleyebileceğinizi sanmıyorum. Aslında Etkinleştir ve Doğrula, kaynağın bir durum makinesinde yeni bir duruma değiştiğini söylemenin dolaylı yoludur. REST bunu modelleme yeteneğine sahiptir.
Darrel Miller

@Darrel, sanırım REST'in REST'te yeni olan birçok insan için zor olabilecek bir kısmına dikkat çekiyorsunuz. "X kaynağını doğrula" işlemini nasıl gerçekleştirebilirsiniz? Bence zor olan şey, durumun değişmesine neden olabilecek bir operasyon olması, ancak yeni durumun, yapılan talebin bir sonucu olmasıdır.
Sean

6

Etkinleştirme ve doğrulama gereksinimleri, bir kaynağın durumunu değiştirmeye çalıştığınız durumlardır. Bir siparişin "tamamlandı" veya başka bir talebin "gönderildi" olması farklı değildir. Bu tür bir devlet değişikliğini modellemenin çok sayıda yolu vardır, ancak sık sık işe yaradığını bulduğum bir tanesi, aynı durumdaki kaynaklar için toplama kaynakları oluşturmak ve ardından kaynağı, durumu etkilemek için koleksiyonlar arasında taşımaktır.

Örneğin,

/ActiveParameters
/ValidatedParameters

Bir parametre kümesini aktif hale getirmek istiyorsanız, bu grubu ActiveParameters koleksiyonuna ekleyin. Parametre kümesini varlık gövdesi olarak iletebilir veya bir url'yi sorgu parametresi olarak aşağıdaki gibi iletebilirsiniz:

POST /ActiveParameters?parameter=/Parameters/{Id}

Aynı şey / ValidatedParameters ile de yapılabilir. Parametreler geçerli değilse, sunucu, parametreleri doğrulanmış parametrelerin toplanmasına ekleme isteğine "Kötü İstek" i döndürebilir.


1

Aşağıdaki Meta kaynak ve yöntemlerini öneririm.

Parametreleri etkin hale getirin ve / veya doğrulayın:

> PUT /parameters/<id>/meta HTTP/1.1
> Host: example.com
> Content-Type: application/json
> Connection: close
>
> {'active': true, 'require-valid': true}
>
< HTTP/1.1 200 OK
< Connection: close
<

Parametrelerin etkin ve geçerli olup olmadığını kontrol edin:

> GET /parameters/<id>/meta HTTP/1.1
> Host: example.com
> Connection: close
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Connection: close
<
< {
<     'active': true,
<     'require-valid': true,
<     'valid': {'status': false, 'reason': '...'}
< }
<

Anladığım kadarıyla, soru işlevsellik ile değil, dinlendirici URL'lerin adlandırılmasıyla ilgili, değil mi?
poezn

2
"RESTful URL'ler" ile sınırlı bir soru kötü bir sorudur ve yanıtlanmamalıdır. Bunun yerine, soru "İlişkili yöntemler ve URL'lerle RESTful kaynakları" dikkate alacak şekilde genişletilmeli ve bu şekilde yanıtlanmalıdır.
yfeldblum

Anladığım kadarıyla, soru URL adlandırma kuralları ve adlandırılmış kaynağın yanıtlaması gereken HTTP yöntemleri ile ilgiliydi .
Andrey Vlasovskikh

1

10 yıldan fazla bir süre sonra OP'de talep edilen bir şeyin bir REST mimarisinde nasıl tasarlanabileceğini gerçekten belirten bir cevap olmadığını görmek biraz üzülüyorum, bu yüzden şimdi bunu yapmam gerektiğini hissediyorum.

İlk önce, REST nedir ?! REST veya ReST kısaltması, "Temsili Durum Transferi" anlamına gelir ve bir kaynağın durumunun belirli bir gösterim biçiminde değişimini tanımlar. Temsil biçimi, müzakere edilen medya türüne bağlıdır. Durumunda application/htmltemsil biçimi HTML akışı muhtemelen belli noktalarda belli unsurları konumlandırmak için biçimlendirme bazı stil uygulandıktan sonra, tarayıcıda oluşturulduğu metin içeriği biçimlendirilmiş olabilir.

REST prensip olarak hepimizin bildiği göz atılabilir Web'in genelleştirilmesidir, ancak sadece tarayıcıları değil her türlü uygulamayı hedefler. Bu nedenle, tasarım gereği Web için geçerli olan aynı kavramlar bir REST mimarisi için de geçerlidir. "RESTful" yolunda bir şeyin nasıl elde edileceği gibi bir soru, bir Web sayfasında bir şeyin nasıl elde edileceği sorusunun yanıtlanması ve ardından aynı kavramların uygulama katmanına uygulanması etrafında çözülür.

Web tabanlı bir hesap makinesi genellikle girilen verileri sunucuya göndermeden önce hesaplamak için bazı değerler girmenizi sağlayan bir "sayfa" ile başlayabilir. HTML'de bu genellikle <form>bir istemciye ayarlanabilecek parametreler, isteği gönderilecek hedef konum ve giriş verilerinin gönderilmesinden sonra uygulanacak temsil formatı hakkında öğreten HTML öğeleri aracılığıyla gerçekleştirilir . Bu, örneğin şöyle görünebilir:

<html>
  <head>
    ...
  </head>
  <body>
    <form action="/../someResource" method="post" enctype="application/x-www-form-urlencoded">
      <label for="firstNumber">First number:</label>
      <input type="number" id="firstNumber" name="firstNumber"/>

      <label for="secondNumber">Second number:</label>
      <input type="number" id="secondNumber" name="secondNumber"/>

      <input type="submit" value="Add numbers"/>
    </form>
  </body>
</html>

Yukarıdaki örnek, kullanıcı veya başka bir otomata tarafından doldurulabilen iki giriş alanının olduğunu ve gönderme giriş elemanını çağırdıktan sonra tarayıcının, giriş verilerini application/x-www-form-urlencodedgönderilen bir temsil formatına biçimlendirmeye özen gösterdiğini belirtir. POSTbu durumda , belirtilen HTTP istek yöntemiyle belirtilen hedef konuma . Biz girerseniz 1içine firstNumbergiriş alanına ve 2içine secondNumbergiriş alanı, tarayıcı bir temsilini oluşturur firstNumber=1&secondNumber=2ve hedef kaynağın gerçek isteğinin vücut yükü olarak bu göndermek.

Bu nedenle sunucuya verilen ham HTTP isteği aşağıdaki gibi görünebilir:

POST /../someResource
Host: www.acme.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
Accept: application/html

firstNumber=1&secondNumber=2

Sunucu, hesaplamayı gerçekleştirebilir ve istemcinin bu biçimi anladığını belirttiği gibi, hesaplamanın sonucunu içeren başka bir HTML sayfasıyla yanıt verebilir.

Breton'un zaten işaret ettiği gibi, "RESTful" URL veya URI diye bir şey yoktur. Bir URI / URL kendi türünde bir şeydir ve bir müşteriye / kullanıcıya herhangi bir anlam ifade etmemelidir. Yukarıdaki hesap makinesi örneğinde bir kullanıcı verilerin nereye gönderileceği ile ilgilenmez, sadece giriş girdi alanını tetikledikten sonra talebin gönderilmesi ile ilgilenir. Görevi gerçekleştirmek için gereken tüm bilgiler sunucu tarafından zaten verilmelidir.

Bir tarayıcı ayrıca, isteğin aslında bazı giriş parametreleriyle bir hesap makinesi beslediğinin farkında olmayabilir, aynı zamanda sipariş sürecine devam etmek için sadece bir sonraki form temsilini döndüren bir tür sipariş formu veya tamamen farklı bir tür olabilir. kaynak. Böyle bir durumda HTML spesifikasyonunun talep ettiği şeyi yerine getirir ve sunucunun gerçekte ne yaptığını daha az umursamazdı. Bu kavram, bir tarayıcının, tercih ettiğiniz çevrimiçi mağazadan bazı şeyler sipariş etme, en iyi arkadaşlarınızla sohbet etme, çevrimiçi bir hesapta oturum açma vb. Gibi her türlü şeyi yapmak için aynı temsil biçimini kullanmasını sağlar.

Affordance böyle bazı öğelerin giriş alanı genellikle düğme olarak oluşturulur durumda, ne onunla hiç gerektiği tanımlarınızı gönderin. Bir düğme veya bağlantı söz konusu olduğunda, temel olarak onu tıklatmanızı söyler. Diğer unsurlar farklı mallar taşıyabilir. Böyle bir değerleme, bağlantı ilişkileri yoluyla da ifade edilebilir, yani preloadtemel olarak bir müşteriye, kullanıcı büyük olasılıkla bu içeriği daha sonra alacağı için bağlı kaynağın içeriğini arka planda yükleyebileceğini söyleyen açıklamalı bağlantılar ile ifade edilebilir. Bu bağlantı ilişkileri elbette standartlaştırılmalı veya Web bağlantısıyla tanımlanan ilişki türleri için genişletme mekanizmasını takip etmelidir .

Bunlar Web'de kullanılan ve REST mimarisinde de kullanılması gereken temel kavramlardır. "Bob Amca" Robert C. Martin'e göre bir mimari niyetle ilgilidir ve REST mimarisinin arkasındaki niyet , istemcileri kırmaktan korkmadan sunucuların gelecekte özgürce gelişebilmeleri için sunuculardan istemcilerin ayrıştırılmasıdır. Maalesef bu, çok fazla disiplin gerektiriyor çünkü kaplin tanıtmak veya işi yapmak ve devam etmek için hızlı çözüm üretmek çok kolay. Jim Webber'in bir REST mimarisinde işaret ettiği gibi, bir hizmet sağlayıcı olarak, müşterilerin bir sürecin sonuna kadar takip edecekleri 70'lerin metin tabanlı bir bilgisayar oyununa benzer bir etki alanı uygulama protokolü tasarlamaya çalışmalısınız .

Ne yazık ki gerçekte "REST" API'lerinin bolca yaptığı şey, bunun dışında her şeydir. Genellikle dinamik olarak entegre edilmesi zor olan, API'ya özgü harici belgelerde belirtilen çoğunlukla JSON tabanlı veri alışverişini görürsünüz. Bir isteğin nasıl görünmesi gerektiği biçimi de harici belgelere sabit olarak kodlanır ve bu da URI'leri önceden tanımlanmış tipler döndürecek şekilde yorumlayan çok sayıda uygulamaya yol açarönceden müzakere edilen bazı ortak temsil formatlarını kullanmak yerine. Bu, istemciler artık önceden tanımlanmış URI'ler için belirli bir veri biçimi (not gösterim biçimi değil!) Almayı beklediğinden sunucuların değişmesini önler. Bu özel veri biçimi değişimi ayrıca "veri biçimi" genellikle belirli bir API'ye geldiği için istemcilerin diğer API'larla etkileşime girmesini önler. Geçmişten bu kavramı, Peppol yakın zamanda AS2'yi varsayılan transfer protokolü olarak AS4 ile değiştirerek yeniden hareket etmesine rağmen, bir şekilde kötü olarak kınadığımız Corba, RMI veya SOAP gibi RPC teknolojilerinden geçmişten biliyoruz.

Sorulan asıl soru ile ilgili olarak, verileri csv dosyası olarak göndermek, application/x-www-form-urlencodedtemsil veya benzeri şeyleri kullanmaktan farklı değildir . Jim Webber, sonuçta HTTP'nin yalnızca uygulama etki alanı Web üzerinden belgelerin aktarılması olan bir aktarım protokolü olduğunu açıkça belirtti . İstemci ve sunucu text/csv, RFC 7111'de tanımlandığı gibi en azından her ikisini de desteklemelidir . Bu CSV dosyası, form öğelerini, isteği göndermek için bir hedef öğeyi veya özniteliği ve yapılandırmanın yüklenmesini gerçekleştirmek için HTTP yöntemini tanımlayan bir ortam türünün işlenmesinin bir sonucu olarak oluşturulabilir.

HTML , HAL Formları , halform , ion veya Hydra gibi formları destekleyen birkaç medya türü vardır . Şu anda, giriş verilerini otomatik olarak text/csvdoğrudan kodlayabilen bir medya türünün farkında değilim, bu yüzden IANA'nın medya türü kayıt defterine tanımlanması ve kaydedilmesi gerekebilir .

Tüm parametre setinin yüklenmesi ve indirilmesi sanırım bir sorun olmamalı. Daha önce de belirtildiği gibi, bir istemci işlemek üzere yeni içerik almak için URI'yi kullanacağı için hedef URI önemli değildir. İşletme tarihine göre filtreleme de zor olmamalıdır. Ancak burada sunucu, istemcinin seçebileceği tüm olanaklara sahip olmalıdır. Son yıllarda, filtrelenmiş bir yanıt almak için belirli bir uç noktada hedeflenebilen SQL benzeri bir dil tanıtan GraphQL ve RestQL gelişti. Bununla birlikte, gerçek bir REST anlamında bu, REST'in arkasındaki fikri ihlal etmektedir: a) GraphQL yani önbelleklemenin en iyi şekilde kullanılmasını bir şekilde önleyen tek bir uç nokta kullanır ve b) mevcut alanların upfrong bilgisini gerektirir, bu da müşterilerin birleştirilmesine neden olabilir kaynağın temel veri modeline.

Belirli yapılandırma parametrelerini etkinleştirmek veya devre dışı bırakmak, bu uygunluğu sağlayan hiper ortam kontrollerini tetiklemekle ilgilidir. HTML formlarında bu basit bir onay kutusu veya bir listede veya bu türde çok satırlı bir seçim olabilir. Forma ve hangi yöntemi tanımladığına bağlı olarak, tüm yapılandırmayı potansiyel olarak gönderebilir PUTveya yapılan değişiklikler hakkında akıllı olabilir ve yalnızca üzerinden kısmi bir güncelleme gerçekleştirebilir PATCH. İkincisi, temel olarak güncellenen değişiklik gösteriminin bir hesaplamasını gerektirir ve sunucuyu, mevcut gösterimi arzu edilene dönüştürmek için gerekli adımlarla besler. PATH spesifikasyonuna göre, bu işlemlerin içinde ya da hiçbirinin uygulanmaması için bir işlem içinde yapılmalıdır.

HTTP, bir sunucunun, değişiklikleri uygulamadan önce alınan bir isteği önceden doğrulamasına izin verir ve teşvik eder. İçin PUT Spec devletler:

Kaynak sunucu PUT temsilinin, sunucunun hedef kaynak için PUT tarafından değiştirilemeyecek veya değiştirilemeyecek kısıtlamalarla tutarlı olduğunu doğrulamalıdır. Bu, özellikle kaynak sunucu, GET yanıtlarında temsil meta verilerinin değerlerini ayarlamak için URI ile ilgili dahili yapılandırma bilgilerini kullandığında önemlidir. Bir PUT temsili hedef kaynakla tutarsız olduğunda, kaynak sunucu, temsili dönüştürerek veya kaynak yapılandırmasını değiştirerek bunları tutarlı hale getirmeli veya temsilin neden uygun olmadığını açıklamak için yeterli bilgi içeren uygun bir hata iletisiyle yanıt vermelidir. 409 (Çakışma) veya 415 (Desteklenmeyen Ortam Türü) durum kodları önerilir,

Örneğin, hedef kaynak her zaman "Metin / html" içerik türüne sahip olacak şekilde yapılandırılmışsa ve PUT olan temsilin "Görüntü / jpeg" içerik türüne sahip olması durumunda, kaynak sunucunun aşağıdakilerden birini yapması gerekir:

a. hedef kaynağı yeni ortam türünü yansıtacak şekilde yeniden yapılandırın;

b. PUT temsilini, yeni kaynak durumu olarak kaydetmeden önce kaynağınkine uygun bir biçime dönüştürmek; veya,

c. 415 (Desteklenmeyen Medya Türü) yanıtıyla, hedef kaynağın "metin / html" ile sınırlı olduğunu, belki de yeni gösterim için uygun bir hedef olabilecek farklı bir kaynağa bağlantı da içerdiğini belirten isteği reddetmek.

HTTP, bir PUT yönteminin, kullanıcı aracısı isteğinin amacı ve kaynak sunucu yanıtının anlamıyla ifade edilebilenin ötesinde bir kaynak sunucunun durumunu tam olarak nasıl etkilediğini tanımlamaz. ...

Bu postayı özetlemek için, bir istemciye gerekli veya desteklenen giriş parametreleri, isteği gönderilecek hedef konum, kullanılacak işlem ve medya türü hakkında bilgi vermenizi sağlayan mevcut bir medya türü kullanmalısınız. istek biçimlendirilmeli veya IANA'ya kaydettirdiğiniz kendi isteğinizi tanımlamalısınız. Girdiyi dönüştürmek istiyorsanız, ikincisi gerekli olabilirtext/csvve ardından CSV sunumunu sunucuya yükleyin. Doğrulama, değişiklikler kaynağa uygulanmadan önce gerçekleşmelidir. Gerçek URI, talebin nereye gönderileceğini belirlemek dışında müşteriler tarafından uygun olmamalıdır ve bu nedenle servis uygulayıcısı tarafından sizin tarafınızdan serbestçe seçilebilir. Bu adımları uygulayarak, sunucu tarafınızı istediğiniz zaman değiştirme özgürlüğüne sahip olursunuz ve istemciler, kullanılan ortam türlerini destekliyorlarsa sonuç olarak kırılmazlar.


0

Düzenleme: Gerçekten de URI GETisteklerin idempotent kalmasını engellerdi.


Bununla birlikte, doğrulama için, bir isteğin geçerliliğini bildirmek için HTTP durum kodlarının kullanılması (yeni bir tane oluşturmak veya mevcut bir 'parametreyi' değiştirmek) Huzurlu bir modele uyacaktır.

400 Bad RequestGönderilen veriler geçersiz / geçersizse ve yeniden gönderilmeden önce isteğin değiştirilmesi gerekiyorsa ( HTTP / 1.1 Durum Kodları ) bir durum kodu ile raporlayın .

Bu, kullanım durumunuzdaki gibi ertelemek yerine, gönderim zamanında doğrulamaya dayanır. Diğer cevaplar bu senaryoya uygun çözümlere sahiptir.


URI'nin bir tanımlayıcı olması amaçlanmıştır. Belirli bir URL kullanmanın yan etkileri olmamalıdır. Bir vekilin bununla ne yapacağını düşünün.
Breton

2
veya google. Bir zamanlar bu tür aptallık nedeniyle tüm ürünlerinin google tarafından silinmesini sağlayan bir web mağazası hakkında bir hikaye okudum.
Breton

0

Bir REST ortamında, her URL benzersiz bir kaynaktır. Kaynaklarınız neler? Bir finansal hesap makinesinin belirgin bir kaynağı yoktur. Parametreleri aradığınız şeyi araştırmanız ve kaynakları çıkarmanız gerekir. Örneğin, bir kredinin amortisman takvimi bir kaynak olabilir. Takvimin URL'si başlangıç ​​tarihi, dönem (ay veya yıl olarak), dönem (faiz birleştirildiğinde), faiz oranı ve başlangıç ​​ilkesini içerebilir. Tüm bu değerlerle, belirli bir ödeme takviminiz var:

http://example.com/amort_cal/2009-10-20/30yrsfixed/monthly/5.00/200000

Şimdi, ne hesapladığınızı bilmiyorum, ancak parametre listesi konseptiniz RESTful gibi görünmüyor. Başka birinin söylediği gibi, yukarıdaki gereksinimleriniz daha fazla XMLRPC'ye benziyor. REST için uğraşıyorsanız, isimlere ihtiyacınız var. Hesaplamalar isimler değil, isimler üzerinde hareket eden fiillerdir. İsimleri calcs'lerinizden çıkarmak için ters çevirmeniz gerekir.


5
Ben burada eğik çizgi kullanmak biraz aptalca olduğunu düşünüyorum, amort_cal ile ne yanlış olur? Date = 2009-10-20 & type = 30yrsfixed & period = aylık & rate = 5.0 & initialamount = 200000? REST bir kaynak olduğu sürece umursamaz. URI Spec yapar gerçi bakımı. Böyle bir şema ile çalışmak için göreli bağlantılar nasıl hayal edersiniz?
Breton

Yine de iyi bir noktaya değindin. Bu "parametrelerin" sunucu tarafında depolanması bile gerekiyor mu? Sadece bir defalık hesaplama ise, neden parametrelerin URL'de bulunduğu sanal bir alan oluşturmuyorsunuz. Dahili durumu değiştirmediğiniz sürece, iyi olmalı.
Breton

1
Ve "parametreler" bir "kaynak" için geçerli değildir. Kaynak, benzersiz tanımlayıcıya sahip tek bir varlıktır. URL'm tek bir kaynağı tanımlar. Parametreli bir URL, parametreleri kullanarak seçtiğiniz bir kaynak koleksiyonunu belirtir.
jmucchiello

2
REST, "CRUDing Resources" 'a dayalı değildir. Tüm sorgu parametrelerinizi yol parçalarına yapıştırmak otomatik olarak RESTful arabirimi oluşturmaz, çünkü artık her permütasyonu bir kaynak olarak adlandırabileceğinizi düşünüyorsunuz. Ne yazık ki, sisteminizdeki kaynakların ne olması gerektiğini belirlemek için uygulayabileceğiniz sihirli bir süreç yoktur. Mekanik bir formül değil, dikkatli bir tasarım gerektirir.
Darrel Miller

2
Bir kez daha, REST mimarisi URL'de ne olduğunu önemsemiyor. URL'nin opak olması amaçlanmıştır . Ayırıcı olarak eğik çizgi, noktalı virgül veya unicode kalp kullanıp kullanmadığınız önemli değildir. Bunu okuyun ve buna cevap verin- söylediğimi hayal ettiğin şeye değil.
Breton
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.