Bir RESTful API'de sorgu parametrelerine karşı yol parametrelerini ne zaman kullanırım?


142

RESTful API'mi oldukça tahmin edilebilir yapmak istiyorum. Sorgu parametrelerini kullanmak yerine URI'yi kullanarak bir veri segmentasyonunun ne zaman yapılacağına karar vermek için en iyi uygulama nedir.

Sayfalamayı, sıralamayı ve gruplandırmayı destekleyen sistem parametrelerinin "?" İşaretinden sonra gelmesi bana mantıklı geliyor. Peki ya koleksiyonunuzu bölümlere ayıran 'durum' ve 'bölge' gibi alanlar veya diğer özellikler? Bunlar sorgu parametreleri de olacaksa, yol parametrelerinin ne zaman kullanılacağını bilmenin temel kuralı nedir?


1
benzer bir soru burada cevaplandı ... stackoverflow.com/questions/3198492/…
Lalit Mehra

Yanıtlar:


241

RESTful API tasarımı için en iyi uygulama, belirli bir kaynağı veya kaynakları tanımlamak için yol parametreleri kullanılırken, bu kaynakları sıralamak / filtrelemek için sorgu parametreleri kullanılır.

İşte bir örnek. Araba adlı bir varlık için RESTful API uç noktaları uyguladığınızı varsayalım. Uç noktalarınızı şu şekilde yapılandırırsınız:

GET /cars
GET /cars/:id
POST /cars
PUT /cars/:id
DELETE/cars/:id

Bu şekilde, yalnızca hangi kaynağın getirileceğini belirlerken yol parametrelerini kullanırsınız, ancak bu, kaynakları hiçbir şekilde sıralamaz / filtrelemez.

Şimdi, GET isteklerinize arabaları renge göre filtreleme özelliğini eklemek istediğinizi varsayalım. Renk bir kaynak olmadığından (bir kaynağın özelliğidir), bunu yapan bir sorgu parametresi ekleyebilirsiniz. Bu sorgu parametresini GET/cars isteğinize şu şekilde eklersiniz :

ALMAK /cars?color=blue

Bu uç nokta, yalnızca mavi arabaların iade edilmesi için uygulanacaktı.

Sözdizimi söz konusu olduğunda, URL adlarınızın tümü küçük harf olmalıdır. Genelde İngilizce'de iki kelime olan bir varlık adınız varsa, deve harflerini değil, sözcükleri ayırmak için kısa çizgi kullanırsınız.

Ör. /two-words


3
Cevabın için teşekkürler Mike. Bu açık ve basit bir metodolojidir; benden bir artı oy değerinde. Yine de, çoğu zaman geliştiriciler 'arabalar / mavi' yaklaşımını tercih ediyorlar, bunun için akıl yürütmelerinin ne olduğunu merak ediyorum ... belki de zorunlu olan alanlar için yol parametreleri yapmaya karar veriyorlar veya belki bunu belirtmek için yapıyorlar veritabanı bu parça tarafından bölümlenir.
cosbor11

1
Sebeplerinin ne olduğundan emin değilim. Dürüst olmak gerekirse, buna katılmıyorum. Bence gelenekleri takip etmek ve basit tutmak en mantıklı olanı. Bunu yaparak, API'nizin tüketicilerinin, işlevselliğine erişmek için tam olarak ne yapmaları gerektiğini daha iyi anlamalarına izin vermiş olursunuz.
Mike

3
peki ya / cars? id = 1 & color = blue yerine cars / 1 /? color = blue. temelde her senaryoda otomobil kaynaklarını filtreliyorsunuz
mko

1
1 numaralı araba sadece bir tane olduğu için yanlış, ancak mavi renkli arabalar belki çoktur. Kimlik ve filtre arasında bir ayrım var
Paul

1
Yol parametrelerini kullanmanın neden bu kadar yaygın olduğuna dair hipotezim, birçok geliştiricinin REST ilkelerini (özellikle Ruby on Rails) iyi bir şekilde kavrayamayan insanlar tarafından tasarlanan çerçevelerden öğrenmiş olmasıdır
Chris Broski

58

Bu konu hakkında düşünmenin temel yolu şudur:

Bir URI, bir kaynak TÜRÜ'nün belirli bir örneğini benzersiz şekilde tanımlayan bir kaynak tanımlayıcıdır. Hayattaki diğer her şey gibi, her nesne (bazı türlerin bir örneği olan), zamanla değişmeyen veya zamansal niteliklere sahiptir.

Yukarıdaki örnekte bir araba, marka, model ve VIN gibi niteliklere sahip - asla değişmeyen ve zamanla değişebilen renk, süspansiyon vb. Özelliklere sahip çok somut bir nesnedir. Dolayısıyla, URI'yi zaman içinde değişebilen özniteliklerle (zamansal) kodlarsak, aynı nesne için birden çok URI ile sonuçlanabilir:

GET /cars/honda/civic/coupe/{vin}/{color=red}

Ve yıllar sonra, bu aynı arabanın rengi siyaha dönerse:

GET /cars/honda/civic/coupe/{vin}/{color=black}

Araba örneğinin kendisinin (nesnenin) değişmediğini unutmayın - sadece değişen renktir. Aynı nesne örneğini gösteren birden çok URI'ye sahip olmak, sizi birden çok URI işleyicisi oluşturmaya zorlar - bu verimli bir tasarım değildir ve elbette sezgisel değildir.

Bu nedenle, URI yalnızca hiçbir zaman değişmeyecek ve ömrü boyunca bu kaynağı benzersiz şekilde tanımlamaya devam edecek parçalardan oluşmalıdır. Değişebilecek her şey, aşağıdaki gibi sorgu parametreleri için ayrılmalıdır:

GET /cars/honda/civic/coupe/{vin}?color={black}

Alt satır - polimorfizmi düşünün.


2
İlginç paradigma .. Bu yaygın olarak kullanılan bir tasarım modeli mi? Belgelerinde bunu kullanan bazı API'ler veya bu stratejiyi özetleyen bazı referanslar sağlayabilir misiniz?
cosbor11

1
"Bir URI, bir kaynak TÜRÜNÜN belirli bir örneğini benzersiz şekilde tanımlayan bir kaynak tanımlayıcıdır" yazdığınızda "TÜR" ü vurgulamanızı seviyorum. Bunun önemli bir ayrım olduğunu düşünüyorum.
jrahhali

15

Bir REST API'de, öngörülebilir URI'larla fazla ilgilenmemelisiniz. URI öngörülebilirliğinin önerisi, RESTful mimarisinin yanlış anlaşılmasına işaret ediyor. Bir müşterinin URI'leri kendilerinin oluşturması gerektiğini varsayar, ki bunu gerçekten yapmamaları gerekir.

Ancak, gerçek bir REST API değil, 'REST'den ilham alan' bir API (Google Drive gibi) oluşturduğunuzu varsayıyorum. Bu durumlarda temel kural, 'yol parametreleri = kaynak tanımlama' ve 'sorgu parametreleri = kaynak sıralama' şeklindedir. Öyleyse, soru şu hale gelir, kaynağınızı durum / bölge OLMADAN benzersiz bir şekilde tanımlayabilir misiniz? Cevabınız evet ise, o zaman belki bir sorgu parametresi. Hayır ise, o zaman bir yol parametresidir.

HTH.


12
Katılmıyorum, iyi bir API öngörülebilir olmalıdır; RESTful veya başka türlü.
cosbor11

3
Ben öyle düşünüyorum. Uç noktaları keyfi olarak adlandırmak yerine, URI'nin nasıl oluşturulduğuna dair kafiye ve sebep olmalıdır. Belgelere sürekli başvurmadan bir API istemcisi sezgisel olarak yazılabildiğinde, bence iyi bir API yazmış olursunuz.
cosbor11

2
"Sürekli dokümantasyona başvurmadan bir API istemcisi sezgisel olarak yazılabildiğinde". REST anlayışımızın farklı olduğunu düşündüğüm yer burasıdır ... API istemcisinin asla bir URL 'oluşturması' gerekmez. Bunu önceki API çağrısının yanıtından seçmeleri gerekir. Benzetme olarak bir web sitesini alırsanız ... facebook.com'a gidersiniz, ardından etkinlikler sayfasına bir bağlantı seçersiniz. Facebook etkinliklerinin URL'sinin 'tahmin edilebilir' olup olmadığı umrunda değil, çünkü onu yazmıyorsunuz. Oraya hipermedya bağlantıları üzerinden ulaşabilirsiniz. Aynısı REST api için de geçerlidir. Öyleyse, URI'leri sizin (sunucu) için anlamlı hale getirin, ancak istemciyi değil
Oliver McPhee

2
Not eklendi. Bu, URI'lerin anlaşılması kolay bir model izlememesi gerektiği anlamına gelmez, sadece bunun bir RESTful API kısıtlaması olmadığı anlamına gelir. Bu alandaki en büyük sorun, insanların bir müşterinin URL'leri kendilerinin oluşturması gerektiğini varsaymasıdır. İstemci ve sunucu arasında olmaması gereken bir bağlantı oluşturduğu için olmamalıdır. (örneğin - sunucu bundan sonra tüm istemci uygulamalarını kesmeden bir URL'yi değiştiremez). Bir REST API'de, sunucu bunları istediği gibi değiştirebilir.
Oliver McPhee

3
Şu kelimeleri kullanmak için +1: "'yol parametreleri = kaynak tanımlama' ve 'sorgu parametreleri = kaynak sıralama'". Bu gerçekten benim için durumu açıklığa kavuşturdu.
Doug

3

Bir zamanlar ana kaynağın olduğu bir API tasarladım people. Genellikle kullanıcılar filtrelenmeyi talep ederlerdi, peopleböylece kullanıcıların /people?settlement=urbanher seferinde olduğu gibi bir şeyi aramasını önlemek için , /people/urbandaha sonra kolayca eklememi sağlayan uyguladım /people/rural. Ayrıca bu, /peopledaha sonra herhangi bir kullanım olacaksa tam listeye erişim sağlar . Kısacası, benim mantığım ortak alt kümelere bir yol eklemekti

Gönderen burada :

Yaygın sorgular için takma adlar

API deneyimini ortalama bir tüketici için daha keyifli hale getirmek için, koşul kümelerini kolayca erişilebilir RESTful yollara paketlemeyi düşünün. Örneğin, yukarıdaki yakın zamanda kapatılan biletler sorgusu şu şekilde paketlenebilir:GET /tickets/recently_closed


1

Genel olarak konuşursak, kaynakta açık bir 'hiyerarşi' olduğunda yol parametrelerini kullanma eğilimindeyim, örneğin:

/region/state/42

Bu tek kaynağın bir durumu varsa, aşağıdakilerden biri yapılabilir:

/region/state/42/status

Bununla birlikte, eğer 'bölge' açığa çıkan kaynağın gerçekten bir parçası değilse, muhtemelen sorgu parametrelerinden birine aittir - sayfalandırmaya benzer (bahsettiğiniz gibi).


0

Segmentasyon daha hiyerarşiktir ve "güzeldir" ancak sınırlayıcı olabilir.

Örneğin, üç segmentli bir url'niz varsa, her biri marka, model ve renk yoluyla bir araba aramak için farklı parametreler geçirir:

www.example.com/search/honda/civic/blue

Bu çok güzel bir url ve son kullanıcı tarafından daha kolay hatırlanıyor, ama şimdi bu yapıya takılıp kaldınız. Arama sırasında kullanıcının TÜM mavi arabaları veya TÜM Honda Civics'i arayabilmesi için bunu yapmak istediğinizi varsayalım. Bir sorgu parametresi bunu çözer çünkü bir anahtar-değer çifti verir. Böylece geçebilirsin:

www.example.com/search?color=blue
www.example.com/search?make=civic

Artık değere anahtarı aracılığıyla başvurmanın bir yolu var - sorgu kodunuzda "renk" veya "yap".

Aşağıdakiler gibi bir tür anahtar değer yapısı oluşturmak için muhtemelen daha fazla segment kullanarak bunu aşabilirsiniz:

www.example.com/search/make/honda/model/civic/color/blue

Umarım mantıklıdır ..


-2

Örnek URL: /rest/{keyword}

Bu URL, yol parametreleri için bir örnektir. Bu URL verilerini kullanarak elde edebiliriz @PathParam.

Örnek URL: /rest?keyword=java&limit=10

Bu URL, sorgu parametreleri için bir örnektir. Bu URL verilerini kullanarak elde edebiliriz @Queryparam.

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.