Bir koleksiyonu PUT veya DELETE ile kısmen değiştirmek uygun mudur?


21

Bir ürün grubundaki ürün koleksiyonum var, örneğin:

product-groups/123/products
  1. Ben gerekiyorsa eklemek koleksiyonuna, ben sadece geçmesini Tamam bazı PUT ürünler?

  2. Ben silmeniz gerekirse bazı koleksiyonundaki ürünleri, ben geçmesini Tamam filtre verilerini SİL ile (kimlikleri dizisi)?

İşlevselliği ReST ruhunda uygulamanın en iyi yolu nedir?

Düzenleme: öğeler, temel olarak ürünlerin kimlikleri olan, ayrı varlıklara bağlantılardır.


Ürünler grubundaki öğeler başka yerlerde yönetilen ayrı kaynaklar var mı? Yoksa bunlar sadece ürün grubu koleksiyonunun bir parçası mı? Ayrı ise ürünler birden fazla ürün grubuna ait olabilir mi?
Martijn Pieters

2
belki PATCH Bu özellik, bir kaynağa kısmi değişiklikler uygulamak için kullanılan yeni HTTP / 1.1 [RFC2616] yöntemini PATCH olarak tanımlar.
Esailija

Bir ürün (ID) birkaç ürün grubuna ait olabilir.
kullanici151851 22.03.2013

Nasıl PATCH yapılacağını söylemenin bilinen bir yolu (en iyi uygulama) var mı yani koleksiyona ürün ekleme veya silme?
kullanici151851

Yanıtlar:


10

Genel olarak x'in tüm koleksiyonunu temsil eden bir son noktaya sahipsiniz :

/products

Diyelim ki, tek bir ürünü güncellemek istiyorsanız, bir PUT yapın /products/{id}. Tek bir ürünü kısmen güncellemek istiyorsanız (her alanı güncellemiyorsanız), ayrıca bir PATCH kullanabilirsiniz /products/{id}. Aynı şey, tek bir varlığın silinmesi için de geçerlidir ( DELETE to /products/{id}).

Eğer bir hedeflemek istiyorsanız tek Ressource, sen hangi yoldan hak bekar , değiştirmek istediğiniz ressource.

Programı bozan tek eylem, kaynakların yaratılmasıdır . Bir bütün olarak toplanmasını hedefleyen bir Ressource oluştururken, demek POST için /products.

Bununla birlikte, toplama işlemini bir bütün olarak etkileyen işlemler için hedefin uygun toplama bitiş noktasına gitmesi gerektiği açıktır.

Örneğin, kırmızı olan bir ürün alt grubunu almak istiyorsanız,

GET için /products?colour=red.

Yani, bunların tümünü silmek istiyorsanız, SİLİNİZ /products?colour=red . Veya ürünlerden bazılarını silmek idisterseniz, DELETE (SİLME) yapabilirsiniz /products?id=1&id=2&id=3 .

Kaynakların toplu olarak oluşturulmasına ne dersiniz ? Koleksiyonunuzu sadece için POST . Aynı PUT ve PATCH için de geçerli .[{...},{...},{...}]/products

Bu gerçekten basit.

Sorularınıza cevap vermek için:

Koleksiyona eklemem gerekirse, sadece PUT’lu bazı ürünlerden geçmem uygun mudur?

Sadece sorun değil, böyle yapmaya teşvik edilirsiniz.

Bazı ürünleri koleksiyondan silmem gerekirse, DELETE ile filtre verilerini (bir dizi kimlik) iletmem tamam mı?

Sorun yok. Eneko Alonso belirttiği gibi, bazen vardır bulkoperations yani, bir "kontrol" -endpoints yoluyla kapsüllenmiş SONRASI tetik (kompleks) işlemleri için kullanılır.


2
PUT bir değiştirme işlemidir. "Bazı ürünlerle" toplama uç noktasındaki PUT'u çağırmak, "bazı ürünler" listesine dahil olmayan herhangi bir ürünü silmelidir (OP'nin durumunda, ilişkiyi silmek). Öğe eklemek için kullanılabilirken, (bence) OP'nin beklediği gibi olmayan öğeleri de kaldırmalıdır. İlk soruya verdiğiniz cevabı buna göre düzeltmelisiniz.
claytond

@claytond: Kısmi bir güncelleme yapıldığı PATCHve tamamen değiştirildiği sürece, cevabın iyi olduğunu farz ediyorum PUT.
9000,

4
9000 @. Tabii ki, ancak cevap şu anda "koleksiyona eklemek için teşvik ediliyorsunuz ... derler ..." sadece PUT'lu bazı ürünleri geçerek "diyor. Bu kesinlikle yanlış. POST'a teşvik edildi. PUT Able ... ama sadece (bazı) öğeleri geçerek.
claytond

5

Genellikle, REST yöntemleri tek bir varlık / nesne (CRUD) üzerinde çalışmayı amaçlamaktadır.

Birkaç seçenek var:

  • Koleksiyonlarınızı varlık olarak kabul edin ve POST ile güncelleyin
  • Alternatif, REST dışı işlemler oluşturun

Bunlardan ilki REST standartlarına uyar, ancak koleksiyon nesneleriniz / varlıklarınız çok büyük olabileceğinden pahalı olabilir (yalnızca bir ürünü eklemek / kaldırmak için binlerce ürün içeren bir grubu güncellemek ağır bir istek olacaktır).

İkinci seçenek, REST'i CRUD işlemlerinin ötesine uzatmanın bir yolu olarak birçok API tarafından tercih edilir.

Örneğin:

GET product-groups/123/products (list all the products in the group)
POST product-groups/123/products/append (POST a list of new product ids to append to the group)
POST product-groups/123/products/remove (POST a list of product ids to remove from the group)

Birçok API bu genişletilmiş işlemler için her zaman POST kullanır, ancak hiçbir şey sizi diğer http yöntemlerini (GET ve DELETE'in boş bir gövdeye sahip olması dışında) kullanmanızla sınırlı kullanmaz.


Tabii ki, hedefe ulaşmak için birkaç yöntem vardır. En iyi uygulama hangisi? Hangisi daha geleceği kanıtlayacak?
user151851

4
@ user151851: Toplam REST uygunluğu (eğer böyle bir şey varsa) yüce bir hedeftir. Buradaki yaklaşım taslağı, daha doğrusu “gerçekçi dünyada” kullanılan bir yaklaşımı benimsemeye çalıştığından, aslında, temel olarak bir standart dışı hale getirdiğinden, daha gerçekçi görünüyor. Bu alacağın kadar gelecek kanıtı ile ilgili.
Robert Harvey,

2
URL’de "append" ve "delete" kullanarak özel fiiller getirmiyor muyuz? Bu şekilde, API'nin nasıl kullanıldığını açıklamamız gerekecektir. Sahip olduğumuz şeyi yani HTTP yöntemlerini tekrar kullanmamalı mıyız? Bu durumda eylemler iyi bilinmektedir.
user151851, 22.03.2013

7
Bu cevaba giren başka biri için: Yanlış. @ User151851'de belirtildiği gibi, bu, fiilleri olabildiğince RESTful olmayan URL'ye tanıtır. Asıl soruya gelince, büyük bir cevabım yok, ama bu değil.
umbrae

"Uzantı" products/collection, öğelerin "zarfını" döndüren ve zarf içeriğinin bir PUT ile değiştirilmesini sağlayarak daha kaynak odaklı olabilir mi? "İşte tam olarak koleksiyondaki öğelerin olmasını istediğim gibi" gibi.
Luke Puplett

3

Sadece önceki cevapları / yorumları kesinleştirmek için.

Bildiğim kadarıyla POST, koleksiyona tekil unsurlar ekleme yöntemidir.

SİLME, tek bir öğeyi koleksiyondan silme yöntemidir. Her iki senaryo da tamamen RESTful.

Ancak, tek bir öğeyi veya tüm koleksiyonu yönlendirmek için uygun URI kullanmanız gerekir.

Örneğin, koleksiyona öğe eklemek için, aşağıdaki URI’ye POST verisi göndermelisiniz:

https://www.factory.net/products/

Tek bir ürünü koleksiyondan silmek için, aşağıdaki gibi bir şeye istek gönderme DELETE yöntemini kullanabilirsiniz:

https://www.factory.net/products/108/

PATCH yöntemi, koleksiyondaki bazı öğeleri güncellemek için kullanılabilir. Örneğin, yalnızca bir öğedeki bir alanı güncellemeniz gerektiğinde. Çok büyük bir koleksiyon için eksiksiz bir kaynak gösterimi koymak çok maliyetli bir işlem olabilir.


2

Prensip olarak, tüm RESTful işlemleri bir koleksiyonda geçerlidir, ancak fiillerin anlamlarının bir koleksiyona nasıl uygulandığını anladığınızdan emin olun:

  • PUT tam bir yerine geçer.

    • Eğer bir singleton PUT (örneğin /item/{id}) ve bırakınname dışarıda , temizlenmiş veya boş veya benzeri bir şey olarak ayarlanmalıdır.
    • Bir koleksiyona KOŞUN ve bir öğe içermiyorsanız , koleksiyondan kaldırılmalıdır .

    PUT, öğe eklemek için kullanılabilirken, "tüm" öğeleri göndermelisiniz. "Bazı" öğelerin gönderilmesi işlemin kaldırılmasıyla sonuçlanmalıdır (OP'nin istediği şey olmadığını farz ediyorum).

  • SİL daha sezgiseldir. Koleksiyon veya filtrelenmiş alt kümelerinin silinmesi geçerlidir. Yalnızca filtrede bulunan öğeler etkilenmelidir.

  • PATCH de geçerlidir. Teoride, "işlemlerin" bir listesini vermeniz gerekiyordu. Örneğin, teknik olarak şöyle bir şey göndermelisiniz:

    [{ 
        "action": "update",
        "id": <id>,
        "value": {...}
    },{
        "action": "add",
        "value": {...}
    }, ...]
    

    Uygulamada, bir UPSERT (güncelleme veya ekleme) mantığı kullanarak her bir öğenin işlendiği kısmi nesne listesini kabul eden bir API görmek daha yaygındır.

  • Teknik olarak, POST "kaynağın kendi semantiğine göre" girdisini işlemelidir.

    • Uygulamada POST normalde "oluşturma" işlemleri için kullanılır.
    • Bununla birlikte, POST standart olmayan çağrılar için de kullanılan bir fiildir. Eylem bitiş noktalarının kesinlikle RESTful olup olmadığına dair güçlü tartışmalar olsa da ("hayır" larla karşı karşıyayım), eğer gibi bir son noktaya bir istek gönderiyorsanız, POST uygun fiildir {resource}/activate.

NOT: Koleksiyonlarda GET olmayan işlemleri kullanırken, başarı ve başarısızlık tanımını dikkatlice düşünün. REST size kısmi başarıyı iletmek için iyi bir yol vermiyor. İyi bir varsayılan işlem, tümünü ya da hiçbiri başarı kriteri olan bir işlemde işlem yapacağınızı varsaymaktır. İstediğiniz bu değilse, muhtemelen doğrudan koleksiyonuyla etkileşime girmemelisiniz.

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.