@QueryParam vs @PathParam ne zaman kullanılır?


276

Burada sorulan soruyu sormuyorum: @PathParam ve @QueryParam arasındaki fark nedir

Bu bir "en iyi uygulamalar" veya konvansiyon sorusu.

@PathParamVs ne zaman kullanılır @QueryParam?

Karar hakkında bilgi modelini ayırt etmek için bu ikisini kullanmak olabilir. LTPO'mun altında mükemmel gözlemden daha azını açıklayayım.

PathParam kullanımı, bir bilgi ağacının dalına güzelce düşen bilgi kategorisine ayrılabilir. PathParam, varlık sınıfı hiyerarşisine inmek için kullanılabilir.

Oysa QueryParam bir sınıf örneğini bulmak için öznitelikleri belirtmek üzere ayrılmış olabilir.

Örneğin,

  • /Vehicle/Car?registration=123
  • /House/Colonial?region=newengland

/category?instance

@GET
@Path("/employee/{dept}")
Patient getEmployee(@PathParam("dept")Long dept, @QueryParam("id")Long id) ;

vs /category/instance

@GET
@Path("/employee/{dept}/{id}")
Patient getEmployee(@PathParam("dept")Long dept, @PathParam("id")Long id) ;

vs ?category+instance

@GET
@Path("/employee")
Patient getEmployee(@QueryParam("dept")Long dept, @QueryParam("id")Long id) ;

Bunu yapmanın standart bir kuralı olduğunu düşünmüyorum. Var mı? Ancak, insanların yukarıda örneklediğim gibi bilgilerini ayırt etmek için PathParam vs QueryParam'ı nasıl kullandıklarını duymak isterim. Ayrıca uygulamanın arkasındaki nedeni duymak isterim.


Yanıtlar:


245

REST böyle bir standart olmayabilir, ancak genel REST belgelerini ve blog yayınlarını okumak, API URL'lerini yapılandırmanın iyi bir yolu için size bazı yönergeler vermelidir. Çoğu dinlenme API'sı yalnızca yolda kaynak adlarına ve kaynak kimliklerine sahip olma eğilimindedir. Gibi:

/departments/{dept}/employees/{id}

Bazı REST API'leri filtreleme, sayfalandırma ve sıralama için sorgu dizeleri kullanır, ancak REST katı bir standart olmadığından, github ve stackoverflow gibi bazı REST API'lerini kontrol etmenizi ve kullanım durumunuz için neyin işe yarayabileceğini görmenizi öneririm .

Gerekli parametreleri yola koymanızı öneririm ve isteğe bağlı parametreler kesinlikle sorgu dizesi parametreleri olmalıdır. İsteğe bağlı parametreleri yola koymak, farklı kombinasyonlarla eşleşen URL işleyicileri yazmaya çalışırken gerçekten dağınık hale gelecektir.


73
" Gerekli parametreleri yola
koymanızı

1
Bu kongre koyun istek için kullanılan, hem de biz db varlığın belirli bir sürümünü güncellemek istiyorum Diyelim gerektiğini URI olmalıdır PUT /depatments/{dept}/employees/{id}/{version}ve sürümü isteğe bağlı olmak ya olması gerektiği PUT /depatments/{dept}/employees/{id}?version=12ve sürümü isteğe bağlı olmak
iyi dilek

Bu durumda, tavsiye ederim: - PUT /depatments/{dept}/employees/{id}/versions/{version}seçilen POST /depatments/{dept}/employees/{id}/versionsbir sürüm ile bir çalışan oluşturmak için
Guillaume Vauvert

90

Bu benim işim.

Kimliğe dayalı bir kayıt almak için bir senaryo varsa, örneğin kimliği 15 olan çalışanın ayrıntılarını almanız gerekir, o zaman @PathParam ile kaynağa sahip olabilirsiniz.

GET /employee/{id}

Tüm çalışanların ayrıntılarını bir kerede yalnızca 10 tane almanız gereken bir senaryo varsa, sorgu parametresini kullanabilirsiniz

GET /employee?start=1&size=10

Bu, çalışan kimliği 1'i başlatmanın on kayıt aldığını söylüyor.

Özetlemek gerekirse, kimliğe göre almak için @PathParam kullanın. Filtre için User @QueryParam veya kullanıcının geçebileceği sabit seçenekler listeniz varsa.


'@PathParam' ve '@QueryParam' aynı işlevleri sağlıyor mu? '@QueryParam' aynı şeyi yazmanın başka bir yolu mu?
Rishabh Agarwal

1
@RishabhAgarwal her ikisi de aynı işlevselliği sağlamasına rağmen, temiz kod uygulaması, yol değişkeni olarak gerekli bir parametrenin ve sorgu parametresi olarak isteğe bağlı herhangi bir parametrenin koyulması önerilir.
Akhil Ghatiki

@RishabhAgarwal Daha fazla bilgi için Rest API'sı Best Practices
Arun B Chandrasekaran

43

Parametre belirli bir varlığı tanımlarsa, bir yol değişkeni kullanmanız gerektiğini düşünüyorum. Örneğin, blogumdaki tüm yayınları almak için rica ediyorum

GET: myserver.com/myblog/posts

id = 123 ile gönderi almak için,

GET: myserver.com/myblog/posts/123

ancak yayın listeme filtre uygulamak ve 1 Ocak 2013'ten bu yana tüm yayınları almak için,

GET: myserver.com/myblog/posts?since=2013-01-01

İlk örnekte "gönderiler" belirli bir varlığı (blog gönderilerinin tüm koleksiyonunu) tanımlar. İkinci örnekte, "123" ayrıca belirli bir varlığı (tek bir blog yayını) temsil eder. Ancak son örnekte, "since = 2013-01-01" parametresi, yayın koleksiyonunu belirli bir varlık için filtrelemeye yönelik bir istektir. Sayfalandırma ve sıralama başka iyi bir örnektir.

GET: myserver.com/myblog/posts?page=2&order=backward

Umarım yardımcı olur. :-)


8

Ben şahsen "kullanıcı için bu parametreleri içeren bir URL yer imi için mantıklı ise PathParam kullanın" yaklaşımını kullandım.

Örneğin, bir kullanıcı profilinin URL'si bazı profil kimliği parametresi içeriyorsa, bu kullanıcı tarafından yer işareti konabileceğinden ve / veya e-postayla gönderilebildiğinden, bu profil kimliğini bir yol parametresi olarak eklerdim. Ayrıca, bunun bir başka düşüncesi de, URL tarafından belirtilen ve param yolunu içeren sayfanın değişmediğidir - kullanıcı profilini ayarlayacak, kaydedecek ve daha sonra o kadar çok değiştirmesi olası değildir; Bu, web tarayıcılarının / arama motorlarının / tarayıcıların / vb. yola göre bu sayfayı güzel bir şekilde önbelleğe alabileceği anlamına gelir.

URL'de geçirilen bir parametrenin sayfa düzenini / içeriğini değiştirmesi muhtemelse, bunu bir sorgu parametresi olarak kullanırım. Örneğin, profil URL'si kullanıcı e-postasının gösterilip gösterilmeyeceğini belirten bir parametreyi destekliyorsa, bunu bir sorgu parametresi olarak değerlendiririm. (Tartışmalı olarak, &noemail=1veya parametresinin hangi parametrenin bir yol parametresi olarak kullanılabileceğini ve biri üzerinde e-postayla, biri olmadan - 2 ayrı sayfa oluşturduğunu söyleyebilirsiniz, ancak mantıklı olarak durum böyle değil: , gösterilen belirli özelliklere sahip olan veya olmayan aynı sayfadır.

Umarım bu yardımcı olur - açıklamanın biraz bulanık olabileceğini takdir ediyorum :)


Bence bu cevaplar kaynakları rotalarla karıştırıyor. Soru, uygulama içinde gezinmenize yardımcı olan bir web uygulamasının yolları hakkında değil, tipik olarak JSON veya XML döndüren bir REST API'nin kaynakları ile ilgilidir.
Hampus


5

Çok ilginç bir soru.

Her ikisini de kullanabilirsiniz, bu konuyla ilgili katı bir kural yoktur, ancak URI yolu değişkenlerini kullanmanın bazı avantajları vardır:

  • Önbellek : İnternetteki web önbellek hizmetlerinin çoğu, sorgu parametreleri içerdiğinde GET isteğini önbelleğe almaz. Bunu yaparlar çünkü sunucudaki verileri değiştirmek için GET isteklerini kullanan çok sayıda RPC sistemi vardır (başarısız! Get! Güvenli bir yöntem olmalı)

Ancak yol değişkenleri kullanıyorsanız, bu hizmetlerin tümü GET isteklerinizi önbelleğe alabilir.

  • Hiyerarşi : Yol değişkenleri hiyerarşiyi temsil edebilir: / Şehir / Sokak / Yer

Kullanıcıya verilerin yapısı hakkında daha fazla bilgi verir.

Ancak verilerinizde herhangi bir hiyerarşi ilişkisi yoksa, virgül veya noktalı virgül kullanarak yine de Yol değişkenlerini kullanabilirsiniz:

/ Şehir / boylam, enlem

Kural olarak, parametrelerin sıralaması önemli olduğunda virgül kullanın, sıralama önemli olmadığında noktalı virgül kullanın:

/ IconGenerator / kırmızı, mavi, yeşil

Bu nedenlerin dışında, sorgu dizesi değişkenlerini kullanmanın çok yaygın olduğu bazı durumlar vardır:

  • HTML form değişkenlerini otomatik olarak URI'ye koymak için tarayıcıya ihtiyacınız olduğunda
  • Algoritma ile uğraşırken. Örneğin, google motoru sorgu dizeleri kullanır:

http: // www.google.com/search?q=rest

Özetle, bu yöntemlerden birini kullanmanın güçlü bir nedeni yoktur, ancak ne zaman yapabiliyorsanız URI değişkenlerini kullanın.


2

Yukarıda belirtildiği gibi, REST bir standart değildir. Ancak, standartlara dayalı bir URI kuralı uygulamak istiyorsanız oData URI kuralını göz önünde bulundurabilirsiniz . Ver 4 bir OASIS standardı olarak onaylanmıştır ve Apache Olingo aracılığıyla Java da dahil olmak üzere çeşitli diller için oData için kütüphaneler bulunmaktadır . Red Hat, Citrix, IBM, Blackberry, Drupal, Netflix Facebook ve SAP gibi diğer endüstri oyuncularının da desteğini aldığı için Microsoft'tan bir spawn'ın sizi ertelemesine izin vermeyin

Burada daha fazla benimseyen listeleniyor


2

Wikipedia'dan: Tekdüzen Kaynak Bulucu

Genellikle hiyerarşik biçimde düzenlenmiş, eğik çizgilerle ayrılmış bir dizi segment olarak görünen veri içeren bir yol .

Hiyerarşik olmayan verilerin bir sorgu dizesini içeren, önceki kısımdan bir soru işareti (?) İle ayrılmış isteğe bağlı bir sorgu .

- URL'nin kavramsal tasarımına göre, hiyerarşik veriler / yönergeler / konumlandırıcı bileşenleri için bir PathParam uygulayabilir veya veriler hiyerarşik olmadığında bir QueryParam uygulayabiliriz. Bu mantıklıdır çünkü yollar doğal olarak sıralanmıştır, oysa sorgular keyfi olarak sıralanabilen değişkenler içermektedir (sırasız değişken / değer çiftleri).

Önceki bir yorumcu şunu yazdı:

Parametre belirli bir varlığı tanımlarsa, bir yol değişkeni kullanmanız gerektiğini düşünüyorum.

Başka biri yazdı,

Kimliğe göre almak için @PathParam kullanın. Filtre için User @QueryParam veya kullanıcının geçebileceği sabit seçenekler listeniz varsa.

Bir diğeri,

Gerekli parametreleri yola koymanızı öneririm ve isteğe bağlı parametreler kesinlikle sorgu dizesi parametreleri olmalıdır.

- Ancak, belirli varlıkları tanımlamak için esnek, hiyerarşik olmayan bir sistem uygulanabilir! Bir SQL tablosunda birden çok benzersiz dizin olabilir ve varlıkların benzersiz bir dizin içeren alanların herhangi bir kombinasyonu kullanılarak tanımlanmasına izin verebilirsiniz! Farklı kombinasyonlardan (yönlendirenler) bağlantılar için farklı kombinasyonlar (belki de farklı şekilde sıralanmıştır) kullanılabilir. Bu durumda, tek tek varlıkları tanımlamak için kullanılan hiyerarşik olmayan verilerle ilgileniyor olabiliriz - ya da diğer durumlarda yalnızca belirli değişkenleri / alanları (benzersiz dizinlerin belirli bileşenleri) belirtebilir ve bir liste / kayıt kümesi alabiliriz. Bu gibi durumlarda URL'leri QueryParams olarak uygulamak daha kolay, daha mantıklı ve makul olabilir!

Uzun bir onaltılık dize, yolun geri kalanındaki anahtar kelimelerin değerini azaltabilir / azaltabilir mi? Değişkenleri / değerleri yola veya sorguya yerleştirmenin olası SEO sonuçlarını dikkate almaya değer olabilir.ve adres çubuğunun içeriğini düzenleyerek kullanıcıların URL'lerin hiyerarşisinde geçiş yapabilmesini / keşfetmesini isteyip istemediğimizin insan arayüzü sonuçları. 404 Bulunamadı sayfam, bozuk URL'leri üst öğelerine otomatik olarak yönlendirmek için SSI değişkenlerini kullanıyor! Arama robotları da yol hiyerarşisinde geçiş yapabilir. Öte yandan, kişisel olarak, URL'leri sosyal medyada paylaştığımda, herhangi bir özel benzersiz tanımlayıcıyı manuel olarak çıkarıyorum - tipik olarak sorguyu URL'den keserek ve yalnızca yolu bırakarak: bu durumda benzersiz tanımlayıcılar yerleştirmede bazı yardımcı programlar var sorguda değil, yolda. Yol bileşenlerinin ham bir kullanıcı arabirimi olarak kullanımını kolaylaştırmak isteyip istemediğimiz, belki de verilerin / bileşenlerin insan tarafından okunabilir olup olmamasına bağlıdır. İnsan tarafından okunabilirlik sorunu bir şekilde hiyerarşi sorunuyla ilgilidir: genellikle, insan tarafından okunabilir anahtar kelimeler olarak ifade edilebilecek veriler de hiyerarşiktir; hiyerarşik veriler genellikle okunabilir anahtar kelimeler olarak ifade edilebilir. (Arama motorlarının kendileri, URL'lerin kullanıcı arayüzü olarak kullanımını artırmak olarak tanımlanabilir.) Anahtar kelime veya direktiflerin hiyerarşileri kesinlikle sipariş edilmeyebilir, ancak genellikle yoldaki alternatif vakaları kapsayabilecek kadar yakındır vebir seçeneği "standart" durum olarak etiketleyin .

Her istek için URL ile cevaplayabileceğimiz temelde birkaç tür soru vardır:

  1. Ne tür bir kayıt / şey istiyoruz?
  2. Hangisiyle ilgileniyoruz?
  3. Bilgileri / kayıtları nasıl sunmak istiyoruz?

Q1 neredeyse kesinlikle en iyi yol veya PathParams tarafından kapsanır. Q3 (muhtemelen rastgele sıralanan isteğe bağlı parametreler ve varsayılan değerler kümesi ile kontrol edilir); neredeyse kesinlikle en iyi QueryParams tarafından kapsanmaktadır. S2: Duruma göre değişir…


2

Alt kaynakların toplanması mantıklı olduğunda, hem sorgu parametrelerini hem de yol parametrelerini destekleyebilirsiniz (örneğin, kaynakların toplanması durumunda).

/departments/{id}/employees
/employees?dept=id

Sorgu parametreleri hiyerarşik ve hiyerarşik olmayan alt kümeleri destekleyebilir; yol parametreleri yalnızca hiyerarşiktir.

Kaynaklar birden çok hiyerarşi sergileyebilir. Hiyerarşik sınırları aşan geniş alt koleksiyonları sorgulayacaksanız kısa yolları destekleyin.

/inventory?make=toyota&model=corolla
/inventory?year=2014

Ortogonal hiyerarşileri birleştirmek için sorgu parametrelerini kullanın.

/inventory/makes/toyota/models/corolla?year=2014
/inventory/years/2014?make=toyota&model=corolla
/inventory?make=toyota&model=corolla&year=2014

Kompozisyon durumunda sadece yol parametrelerini kullanın - bir kaynak üst öğesinden boşanmıyorsa ve tüm çocukların küresel koleksiyonu kendi başına yararlı bir kaynak değildir.

/words/{id}/definitions
/definitions?word=id   // not useful

1

Nedeni aslında çok basit. Bir sorgu parametresi kullanırken "/" gibi karakterler alabilir ve istemcinizin bunları html olarak kodlaması gerekmez. Başka nedenler de var, ancak bu basit bir örnek. Bir yol değişkeninin ne zaman kullanılacağı ile ilgili. Ne zaman ids ile ilgili veya path değişkeni bir sorgu için bir yön olduğunu söyleyebilirim.


1

Ne zaman kullanacağımızı @Queryparamve ne zaman kullanacağımızı bir exapmle veriyorum ve@pathparam

Mesela bir kaynak alıyorum carResourcesınıf

Resouce yönteminizin girdilerini manuel yapmak istiyorsanız, param türünü şu şekilde kullanın; @pathaparameğer kaynak yönteminizin girdileri isteğe bağlıysa, bu param türünü @QueryParamparam olarak saklayın

@Path("/car")
class CarResource
{
    @Get
    @produces("text/plain")
    @Path("/search/{carmodel}")
    public String getCarSearch(@PathParam("carmodel")String model,@QueryParam("carcolor")String color) {
        //logic for getting cars based on carmodel and color
            -----
        return cars
    }
}

Bu özgeçmiş için isteği geç

req uri ://address:2020/carWeb/car/search/swift?carcolor=red

Eğer böyle bir req verirseniz, resouce temel araç modelini ve rengini verir

 req uri://address:2020/carWeb/car/search/swift

Eğer böyle bir req verirseniz, resoce yöntemi sadece hızlı model tabanlı araba görüntüler

req://address:2020/carWeb/car/search?carcolor=red

Eğer böyle verirseniz, ResourceNotFound istisnası elde edeceğiz çünkü araba resouce sınıfında carmodel ilan @pathPrametmelisiniz ve karmodeli reQ uri olarak vermelisiniz, aksi takdirde resouce için req'yi geçmeyecek, ancak rengi geçmezseniz ayrıca neden kaynak için req geçirecek çünkü renk @quetyParamreq isteğe bağlıdır.


0
  1. @QueryParam varsayılan değer ek açıklaması ile rahatlıkla kullanılabilir, böylece sorgu parametresi geçilmezse boş gösterici istisnasını önleyebilirsiniz.

Eğer bir GET isteğinden ayrıştırma sorgu parametreleri istediğinizde, sadece birlikte GET isteği ve açıklama onlarla idare edecek yönteme ilgili parametreyi tanımlayabilir @QueryParamaçıklama

  1. @PathParamURI değerlerini ayıklar ve ile eşleşir @Path. Ve böylece girdi parametresini alır. 2.1 @PathParambirden fazla olabilir ve yöntem bağımsız değişkenlerine ayarlanmıştır

    @Path("/rest")
    public class Abc {
    
        @GET
        @Path("/msg/{p0}/{p1}")
        @Produces("text/plain")
        public String add(@PathParam("p0") Integer param1, @PathParam("p1")  Integer param2 )
        {
            return String.valueOf(param1+param2);
        }
    } 

Yukarıdaki örnekte
http://localhost:8080/Restr/rest/msg/{p0}/{p1},
p0eşleşmeler param1ve p1eşleşmeler param2. URI'sındakiyle Yani
http://localhost:8080/Restr/rest/msg/4/6,
biz sonuç almak 10.

REST Hizmetinde, JAX-RS HTTP isteğinden veri kabul etmek için @QueryParamve @FormParamher ikisini de sağlar . Bir HTTP formu GET ve POST gibi farklı yöntemlerle gönderilebilir.

@QueryParam : GET isteğini kabul eder ve sorgu dizesindeki verileri okur.

@FormParam: POST isteğini kabul eder ve HTML formundan veya ortamın herhangi bir isteğinden veri alır


0

Özetle,

@Pathparam hem Kaynaklar hem de Sorgu Dizesi içinden değer iletmeye çalışır

  • /user/1
  • /user?id=1

@Queryparam yalnızca değer iletme için çalışır Sorgu Dizesi

  • /user?id=1
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.