Kapan menggunakan @QueryParam vs @PathParam

277

Saya tidak mengajukan pertanyaan yang sudah diajukan di sini: Apa perbedaan antara @PathParam dan @QueryParam

Ini adalah "praktik terbaik" atau pertanyaan konvensi.

Bila Anda akan menggunakan @PathParamvs @QueryParam.

Apa yang dapat saya pikirkan adalah bahwa keputusan tersebut mungkin menggunakan keduanya untuk membedakan pola informasi. Biarkan saya ilustrasikan di bawah LTPO saya - pengamatan kurang sempurna.

Penggunaan PathParam dapat dicadangkan untuk kategori informasi, yang akan jatuh dengan baik ke cabang pohon informasi. PathParam dapat digunakan untuk menelusuri hierarki kelas entitas.

Sedangkan, QueryParam dapat dicadangkan untuk menentukan atribut untuk menemukan instance kelas.

Sebagai contoh,

  • /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) ;

Saya tidak berpikir ada konvensi standar untuk melakukannya. Disana? Namun, saya ingin mendengar bagaimana orang menggunakan PathParam vs QueryParam untuk membedakan informasi mereka seperti yang saya contohkan di atas. Saya juga ingin mendengar alasan di balik latihan ini.

Blek Geek
sumber
4
kemungkinan duplikat Kapan menggunakan pathParams atau QueryParams
Joachim Sauer

Jawaban:

245

REST mungkin bukan standar seperti itu, tetapi membaca dokumentasi REST umum dan posting blog harus memberi Anda beberapa panduan untuk cara yang baik untuk menyusun URL API. Sebagian besar API lainnya cenderung hanya memiliki nama sumber daya dan ID sumber daya di jalurnya. Seperti:

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

Beberapa REST API menggunakan string kueri untuk pemfilteran, pagination, dan sorting, tetapi karena REST bukan standar yang ketat, saya sarankan memeriksa beberapa REST API di luar sana seperti github dan stackoverflow dan lihat apa yang bisa bekerja dengan baik untuk use case Anda.

Saya akan merekomendasikan menempatkan parameter apa pun yang diperlukan di jalur, dan parameter opsional apa pun harus menjadi parameter string kueri. Menempatkan parameter opsional di jalur akan menjadi sangat berantakan ketika mencoba menulis penangan URL yang cocok dengan kombinasi berbeda.

theon
sumber
73
" Saya akan merekomendasikan menempatkan parameter yang diperlukan di jalan, dan setiap parameter opsional pasti harus parameter string kueri. " - acungan jempol +1 ya def
smeeb
1
haruskah konvensi ini digunakan untuk permintaan Put juga, katakanlah kita ingin memperbarui versi tertentu dari entitas db, seandainya URI menjadi PUT /depatments/{dept}/employees/{id}/{version}dan versi menjadi opsional atau seandainya PUT /depatments/{dept}/employees/{id}?version=12dan versi menjadi opsional
semoga
Dalam hal ini, saya akan merekomendasikan: - PUT /depatments/{dept}/employees/{id}/versions/{version}untuk membuat karyawan dengan versi yang dipilih - POST /depatments/{dept}/employees/{id}/versionsuntuk membuat karyawan dengan versi yang ditentukan oleh backend
Guillaume Vauvert
90

Inilah yang saya lakukan.

Jika ada skenario untuk mengambil catatan berdasarkan id, misalnya Anda perlu mendapatkan detail karyawan yang idnya 15, maka Anda dapat memiliki sumber daya dengan @PathParam.

GET /employee/{id}

Jika ada skenario di mana Anda perlu mendapatkan rincian semua karyawan tetapi hanya 10 pada satu waktu, Anda dapat menggunakan param kueri

GET /employee?start=1&size=10

Ini mengatakan bahwa mulai karyawan id 1 mendapatkan sepuluh catatan.

Untuk meringkas, gunakan @PathParam untuk pengambilan berdasarkan id. Pengguna @QueryParam untuk filter atau jika Anda memiliki daftar opsi tetap yang dapat dilewati pengguna.

Arun B Chandrasekaran
sumber
apakah '@PathParam' dan '@QueryParam' menyediakan fungsionalitas yang sama? Apakah '@QueryParam' hanyalah cara lain untuk menulis hal yang sama?
Rishabh Agarwal
1
@RishabhAgarwal meskipun keduanya menyediakan fungsionalitas yang sama, praktik kode bersih adalah bahwa, disarankan untuk menempatkan parameter yang diperlukan sebagai variabel path dan parameter opsional apa pun sebagai parameter kueri.
Akhil Ghatiki
@RishabhAgarwal Untuk informasi lebih lanjut, Anda dapat merujuk ke artikel saya Istirahat API Praktik Terbaik
Arun B Chandrasekaran
43

Saya pikir jika parameter mengidentifikasi entitas tertentu Anda harus menggunakan variabel path. Misalnya, untuk mendapatkan semua posting di blog saya, saya minta

GET: myserver.com/myblog/posts

untuk mendapatkan posting dengan id = 123, saya akan meminta

GET: myserver.com/myblog/posts/123

tetapi untuk memfilter daftar posting saya, dan mendapatkan semua posting sejak 1 Januari 2013, saya akan meminta

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

Dalam contoh pertama "posting" mengidentifikasi entitas tertentu (seluruh koleksi posting blog). Pada contoh kedua, "123" juga mewakili entitas tertentu (satu posting blog). Tetapi dalam contoh terakhir, parameter "since = 2013-01-01" adalah permintaan untuk memfilter koleksi posting bukan entitas tertentu. Pagination dan pemesanan akan menjadi contoh yang baik, yaitu

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

Semoga itu bisa membantu. :-)

10Gambar Kertas
sumber
8

Saya pribadi menggunakan pendekatan "jika masuk akal bagi pengguna untuk mem-bookmark URL yang menyertakan parameter ini kemudian gunakan PathParam".

Misalnya, jika URL untuk profil pengguna menyertakan beberapa parameter id profil, karena ini dapat di-bookmark oleh pengguna dan / atau diemailkan di sekitar, saya akan memasukkan id profil itu sebagai parameter path. Juga, pertimbangan lain untuk hal ini adalah bahwa halaman yang dilambangkan oleh URL yang mencakup parameter path tidak berubah - pengguna akan mengatur profilnya, menyimpannya, dan kemudian tidak mungkin banyak berubah dari sana; ini berarti webcrawlers / search engine / browser / etc dapat men-cache halaman ini dengan baik berdasarkan path.

Jika parameter yang dikirimkan dalam URL cenderung mengubah tata letak halaman / konten maka saya akan menggunakannya sebagai queryparam. Misalnya, jika URL profil mendukung parameter yang menentukan apakah akan menampilkan email pengguna atau tidak, saya akan menganggapnya sebagai parameter kueri. (Saya tahu, bisa dibilang, Anda bisa mengatakan bahwa &noemail=1parameter atau apa pun itu dapat digunakan sebagai parameter path dan menghasilkan 2 halaman terpisah - satu dengan email di atasnya, satu tanpa itu - tetapi secara logis bukan itu masalahnya: itu masih halaman yang sama dengan atau tanpa atribut tertentu yang ditampilkan.

Semoga ini bisa membantu - Saya menghargai penjelasannya mungkin agak kabur :)

Liv
sumber
Saya pikir jawaban ini membingungkan sumber daya dengan rute. Pertanyaannya adalah tentang sumber daya REST API, biasanya mengembalikan JSON atau XML, bukan tentang rute aplikasi web, yang membantu Anda menavigasi dalam aplikasi.
Hampus
5

Itu pertanyaan yang sangat menarik.

Anda dapat menggunakan keduanya, tidak ada aturan ketat tentang subjek ini, tetapi menggunakan variabel path URI memiliki beberapa keunggulan:

  • Cache : Sebagian besar layanan cache web di internet tidak men-cache permintaan GET saat mengandung parameter kueri. Mereka melakukan itu karena ada banyak sistem RPC menggunakan permintaan GET untuk mengubah data di server (gagal !! Dapatkan harus menjadi metode yang aman)

Tetapi jika Anda menggunakan variabel jalur, semua layanan ini dapat menembolok permintaan GET Anda.

  • Hirarki : Variabel path dapat mewakili hierarki: / City / Street / Place

Ini memberi pengguna informasi lebih lanjut tentang struktur data.

Tetapi jika data Anda tidak memiliki hubungan hierarki apa pun, Anda masih dapat menggunakan variabel Path, menggunakan koma atau semi-kolon:

/ Kota / bujur, lintang

Sebagai aturan, gunakan koma ketika memesan parameter penting, gunakan semi-kolon ketika pemesanan tidak masalah:

/ IconGenerator / merah; biru; hijau

Terlepas dari alasan itu, ada beberapa kasus ketika sangat umum untuk menggunakan variabel string kueri:

  • Ketika Anda membutuhkan browser untuk secara otomatis memasukkan variabel formulir HTML ke dalam URI
  • Ketika Anda berurusan dengan algoritma. Misalnya mesin google menggunakan string kueri:

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

Singkatnya, tidak ada alasan kuat untuk menggunakan salah satu metode ini tetapi kapan pun Anda bisa, gunakan variabel URI.

jfcorugedo
sumber
2

Seperti yang dicatat, REST bukan standar. Namun, jika Anda ingin menerapkan konvensi URI berbasis standar, Anda dapat mempertimbangkan konvensi URI oData . Ver 4 telah disetujui sebagai standar OASIS dan perpustakaan ada untuk oData untuk berbagai bahasa termasuk Java melalui Apache Olingo . Jangan biarkan fakta bahwa itu adalah spawn dari Microsoft yang membuat Anda kesal karena mendapat dukungan dari pemain industri lain juga , termasuk Red Hat, Citrix, IBM, Blackberry, Drupal, Netflix Facebook dan SAP

Lebih banyak pengguna terdaftar di sini

MikeM
sumber
2

Dari Wikipedia: Uniform Resource Locator

Jalur , yang berisi data, biasanya disusun dalam bentuk hierarkis , yang muncul sebagai urutan segmen yang dipisahkan oleh garis miring.

Kueri opsional , dipisahkan dari bagian sebelumnya dengan tanda tanya (?), Yang berisi string kueri data non-hierarkis .

- Sesuai dengan desain konseptual URL, kami dapat mengimplementasikan PathParam untuk komponen hierarki data / arahan / pencari lokasi, atau mengimplementasikan QueryParam ketika data tidak hierarkis. Ini masuk akal karena jalur secara alami dipesan, sedangkan kueri berisi variabel yang dapat dipesan secara acak (pasangan variabel / nilai tidak teratur).

Seorang komentator sebelumnya menulis,

Saya pikir jika parameter mengidentifikasi entitas tertentu Anda harus menggunakan variabel path.

Yang lain menulis,

Gunakan @PathParam untuk pengambilan berdasarkan id. Pengguna @QueryParam untuk filter atau jika Anda memiliki daftar opsi tetap yang dapat dilewati pengguna.

Lain,

Saya akan merekomendasikan menempatkan parameter apa pun yang diperlukan di jalur, dan parameter opsional apa pun harus menjadi parameter string kueri.

- Namun, orang mungkin menerapkan sistem fleksibel, non-hierarkis untuk mengidentifikasi entitas tertentu! Seseorang mungkin memiliki beberapa indeks unik pada tabel SQL, dan memungkinkan entitas diidentifikasi menggunakan kombinasi bidang apa pun yang membentuk indeks unik! Kombinasi yang berbeda (mungkin juga dipesan secara berbeda), dapat digunakan untuk tautan dari berbagai entitas terkait (pengarah). Dalam kasus ini, kita mungkin berurusan dengan data non-hierarkis, yang digunakan untuk mengidentifikasi entitas individu - atau dalam kasus lain, mungkin hanya menentukan variabel / bidang tertentu - komponen indeks unik tertentu - dan mengambil daftar / set catatan. Dalam kasus seperti itu, mungkin lebih mudah, lebih logis dan masuk akal untuk mengimplementasikan URL sebagai QueryParams!

Bisakah string heksadesimal panjang mencairkan / mengurangi nilai kata kunci di sisa jalur? Mungkin ada baiknya mempertimbangkan implikasi SEO potensial dari menempatkan variabel / nilai di jalur, atau di kueri, dan implikasi antarmuka manusia dari apakah kita ingin pengguna dapat melintasi / menjelajahi hierarki URL dengan mengedit isi bilah alamat. Halaman 404 Tidak Ditemukan saya menggunakan variabel SSI untuk secara otomatis mengarahkan ulang URL yang rusak ke induknya! Robot pencarian juga dapat melintasi hierarki jalur. Di sisi lain, secara pribadi, ketika saya membagikan URL di media sosial, saya secara manual menghapus setiap pengidentifikasi unik pribadi - biasanya dengan memotong kueri dari URL, hanya menyisakan jalur: dalam hal ini, ada beberapa utilitas dalam menempatkan pengidentifikasi unik di jalur daripada di kueri. Apakah kita ingin memfasilitasi penggunaan komponen jalur sebagai antarmuka pengguna mentah, mungkin tergantung pada apakah data / komponen tersebut dapat dibaca oleh manusia atau tidak. Pertanyaan keterbacaan manusia agak berkaitan dengan pertanyaan tentang hierarki: sering, data yang dapat diekspresikan sebagai kata kunci yang dapat dibaca manusia juga bersifat hierarkis; sementara data hierarkis seringkali dinyatakan sebagai kata kunci yang dapat dibaca manusia. (Mesin pencari itu sendiri dapat didefinisikan sebagai memperbesar penggunaan URL sebagai antarmuka pengguna.) Hirarki kata kunci atau arahan mungkin tidak secara ketat dipesan, tetapi biasanya cukup dekat sehingga kita dapat membahas kasus-kasus alternatif di jalur, danberi label satu opsi sebagai kasus "kanonik" .

Pada dasarnya ada beberapa jenis pertanyaan yang dapat kami jawab dengan URL untuk setiap permintaan:

  1. Catatan / hal apa yang kita minta / layani?
  2. Yang mana yang kami minati?
  3. Bagaimana kita ingin menyajikan informasi / catatan?

Q1 hampir pasti paling baik dicakup oleh path, atau oleh PathParams. Q3 (yang mungkin dikendalikan melalui serangkaian parameter opsional yang dipesan secara acak dan nilai-nilai default); hampir pasti paling baik dicakup oleh QueryParams. T2: Tergantung ...

Matthew Slyman
sumber
2

Anda dapat mendukung parameter kueri dan parameter lintasan, misalnya, dalam hal agregasi sumber daya - saat pengumpulan sub-sumber daya masuk akal dengan sendirinya.

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

Parameter kueri dapat mendukung pengesahan hierarkis dan non-hierarkis; parameter jalur bersifat hierarkis saja.

Sumber daya dapat menunjukkan banyak hierarki. Mendukung jalur pendek jika Anda akan menanyakan sub-koleksi luas yang melintasi batas hierarkis.

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

Gunakan parameter kueri untuk menggabungkan hierarki ortogonal.

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

Gunakan hanya parameter jalur dalam hal komposisi - ketika sumber daya tidak masuk akal dipisahkan dari induknya, dan koleksi global semua anak bukanlah sumber daya yang berguna.

/words/{id}/definitions
/definitions?word=id   // not useful
Steve Mitchell
sumber
1

Alasannya sebenarnya sangat sederhana. Saat menggunakan parameter kueri, Anda dapat mengambil karakter seperti "/" dan klien Anda tidak perlu menyandikannya dengan HTML. Ada alasan lain tetapi itu adalah contoh sederhana. Adapun kapan harus menggunakan variabel path. Saya akan mengatakan setiap kali Anda berurusan dengan id atau jika variabel path adalah arah untuk kueri.

Tony
sumber
1

Saya memberikan satu contoh untuk undersand kapan kita menggunakan @Queryparamdan@pathparam

Misalnya saya mengambil satu sumber adalah carResourcekelas

Jika Anda ingin membuat input dari manajatory metode sumber daya Anda maka gunakan tipe param sebagai @pathaparam, jika input dari metode sumber daya Anda harus opsional maka simpan tipe @QueryParamparam sebagai param

@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
    }
}

Untuk sumber daya ini, sampaikan permintaan

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

Jika Anda memberikan req seperti ini, sumber daya akan memberikan model dan warna mobil yang berbasis

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

Jika Anda memberikan req seperti ini, metode sumber daya hanya akan menampilkan mobil berbasis model cepat

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

Jika Anda memberi seperti ini, kita akan mendapatkan pengecualian ResourceNotFound karena di kelas sumber daya mobil saya mendeklarasikan carmodel karena @pathPramitu adalah Anda harus dan harus memberikan carmodel sebagai reQ uri jika tidak, ia tidak akan meneruskan req ke sumber daya tetapi jika Anda tidak lulus warna juga akan meneruskan req ke sumber daya mengapa karena warnanya @quetyParamopsional di req.

DB5
sumber
0
  1. @QueryParam dapat dengan mudah digunakan dengan anotasi Nilai Default sehingga Anda dapat menghindari pengecualian penunjuk nol jika tidak ada parameter kueri yang diteruskan.

Saat Anda ingin mem-parsing parameter kueri dari permintaan GET, Anda bisa mendefinisikan masing-masing parameter ke metode yang akan menangani permintaan GET dan membubuhi keterangan dengan @QueryParamanotasi

  1. @PathParammengekstrak nilai URI dan mencocokkannya dengan @Path. Dan karenanya mendapat parameter input. 2.1 @PathParamdapat lebih dari satu dan diatur ke argumen metode

    @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);
        }
    } 

Dalam contoh di atas
http://localhost:8080/Restr/rest/msg/{p0}/{p1},,
p0cocok param1dan p1cocok param2. Jadi untuk URI
http://localhost:8080/Restr/rest/msg/4/6,
kami mendapatkan hasilnya 10.

Dalam Layanan REST, JAX-RS menyediakan @QueryParamdan @FormParamkeduanya untuk menerima data dari permintaan HTTP. Formulir HTTP dapat dikirimkan dengan metode berbeda seperti GET dan POST.

@QueryParam : Menerima permintaan GET dan membaca data dari string kueri.

@FormParam: Menerima permintaan POST dan mengambil data dari formulir HTML atau permintaan media apa pun

Amlesh Kumar
sumber
0

Singkatnya,

@Pathparam bekerja untuk nilai yang melewati Sumber Daya dan String Kueri

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

@Queryparam bekerja untuk nilai yang melewati hanya String Kueri

  • /user?id=1
ArulRajP
sumber