RESTful API'sında iç içe kaynaklar ne zaman kullanılır?


16

İki kaynağım var: kullanıcılar ve bağlantılar.

Kullanıcıların kendileriyle ilişkili birkaç bağlantısı olabilir. Aşağıdaki URI'da bir kullanıcıyla ilişkili bağlantılara erişebilmeniz için RESTful API'mi tasarladım:

/users/:id/links

Ancak, her zaman sadece bağlantılar için bir URI'ye ihtiyacım var - bazen kullanıcı ne olursa olsun tüm bağlantıları isteyebilirim.

Bunun için var:

/links

Kulağa hoş geliyor mu? Bağlantılar için iki URI'nız mı var?

Bunun yerine URI'li bir kullanıcı için bağlantılara ulaşmalı mıyım acaba:

/links/user/:id veya /links/?user=:id

Bu şekilde, bağlantılar için sadece bir kaynağım var.


3
hmm .. Bu daha zarif görünüyor:/links/user/:id
theMarceloR

7
@theMarceloR: Ben o üç dışında tek örnek değil özellikle berrak bulabilirsiniz. Kaynak bir bağlantı veya kullanıcı için mi? URI, aslında bir sorgu olduğu için iç içe kaynak yöntemi ( /users/:id/links) veya sorgu dizesi yöntemi ( /links/?user=:id) kullanılarak çok daha az belirsizdir . /links/user/:idgüzel görünebilir ve / veya bazı çerçevelerde yönlendirilmesi daha kolay olabilir, ancak aslında oldukça kafa karıştırıcıdır.
Aaronaught

Yanıtlar:


16

Hayır, aynı "şey" için birden fazla kaynağa sahip olmanın yanlış bir yanı yok, bu durumda bağlantı listeleri.

Son zamanlarda aynı sorunla mücadele ediyorduk. Kararımız, iç içe geçmeyecek katı bir mülkiyetin olmadığı tüm kaynaklara sahip olmaktı. Başka bir deyişle, bağlantılar

/links -- all links
/links/:linkid -- a particular link

Daha sonra, bağlantılar koleksiyonundaki filtreler sorgu parametreleri olarak ifade edilir. Belirli bir kullanıcının bağlantılarını almak için şunu kullanırsınız:

/links?user=/users/:userid

Bu aynı zamanda filtrelerin daha kolay bileşimini sağlar:

/links?user=/users/10&since=2013-01-01

Kavramsal olarak anlaşılması kolaydır - bir öğe koleksiyonunuz var ve buna filtreler ekliyorsunuz.

Bununla birlikte, bu yaklaşım hakkında diğer URI adlandırma şemalarından daha "RESTful" diye bir şey yoktur. Bu, geliştiricilerin anlaması ve kucaklaması bizim için kolay okunabilir ve kolay bulduğumuz bir sözleşmedir. REST, kaynak tanımlayıcılarınıza ne koyduğunuzla ilgilenmez.


1
"İç içe geçmemek için sıkı bir mülkiyetin olmadığı tüm kaynaklar" kulağa iyi bir kural gibi geliyor. Çok teşekkürler.
Oliver Joseph Ash

5
Orada söyleyebilirim olan aynı fiziksel varlık için birden fazla kaynak sahip bir şeylerin yanlış, ama bu ne aslında değil. Her bir bağlantının standart bir URL'si (links /: id) bulunurken, yukarıdaki kaynakların her biri aslında filtrelerin uygulandığı tek bir kaynaktır (/ links). Ayrıca, ben ?user=users/:useridsorgu dizesinde tarafından garip ; sadece yanlış olan ne ?userid=:userid?
Aaronaught

2
@Aaronaught: istemciler tüm kaynak tanımlayıcılarına eşit şekilde davranabilmeleri için çıplak kimlikler yerine uri'ye sadık kalmanın nedeni, bir istemcinin yalnızca 'bu kullanıcı tarafından tanımlandığı "/*******"; nerede *opak. ancak aynı tanımlayıcı her zaman bu kaynağa başvurmak için (bağlantılarda olduğu gibi), o kaynağın en güncel sürümünü getirmek için kullanılabilir. bu uri'nin içeriği yalnızca kaynak sunucu tarafından anlaşılır. Bu ayrıca, tanımlayıcıların değişmesi gerektiğinde, örneğin /realm/:businessid/users/:id, istemcinin hiç değişmediği anlamına gelir .
SingleNegationElimination

@TokenMacGuy: Üzgünüm, yorumunuzun hiçbir bölümünü anlamıyorum. Arasındaki pratik fark nedir /users/:userid/linksve /links?userid=:userid? Her iki durumda da tanımlayıcılar değişmez, o kaynağın geçerli sürümünü alır ve istemci bunları aynı şekilde ele alır. Kanonik bir URL diye bir şey yoktur, çünkü bu bir kaynak değildir, bir sorgudur, bu yüzden bunlar sadece iki farklı türden sorgu sözdizimidir. Ayrıca URL yapısı değişirse istemcinin nasıl değişmesi gerekmediği konusunda net değilim; 301'in yerinde olmadığı sürece REST'te kırılma değişikliği olarak kabul edilir.
Aaronaught

1
@Aaronaught: Endişenizi yanlış anlamış olabilirdim. Varsayalım ki /linksbir sorgu arabirimini destekler /links?user=/users/123, istemcide /links?userid=123olmayan kaynak tanımlayıcılarına kara kutu yaklaşımına izin verir . ikincisi, müşterinin bir kullanıcı kimliğinin ne olduğunu ve nasıl alınacağını anlamasını gerektirir, muhtemelen /users/123veya kaynaktan elde ettiği kaynaktan /links/456/user. Birincisi, müşterinin değiştirilmemiş uri'yi kullanabileceği anlamına gelir; varsayalım /links/.../userhipermedya yanıtı verir (örneğin, Location:başlıklar ile).
SingleNegationElimination

1

Benim endişem şudur: / users /: userid / links "links" döndürür, AMA user_id tanımlanmadıysa, bu bir 404 döndürmelidir.

ancak

/ links? userid =: userid, muhtemelen büyük olasılıkla bir hata olan boş bir liste (esas olarak 200) döndürür. Ve oldukça mümkün.

Her ikisi de çalışmasına rağmen, yuvalama size daha sonra çizebileceğiniz ek işlevsellik sağlar.

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.