Parameter matriks URL vs. parameter kueri

176

Saya ingin tahu apakah akan menggunakan parameter matriks atau kueri di URL saya. Saya menemukan diskusi yang lebih tua dengan topik itu tidak memuaskan.

Contohnya

Pada pandangan pertama, params matriks tampaknya hanya memiliki keuntungan:

  • lebih mudah dibaca
  • tidak diperlukan penyandian dan decoding "&" dalam dokumen XML
  • URL dengan "?" tidak di-cache dalam banyak kasus; URL dengan params matriks di-cache
  • parameter matriks dapat muncul di mana saja di jalur dan tidak terbatas pada akhirnya
  • parameter matriks dapat memiliki lebih dari satu nilai: paramA=val1,val2

Namun ada juga kelemahannya:

  • hanya beberapa kerangka kerja seperti parameter matriks dukungan JAX-RS
  • Saat browser mengirimkan formulir melalui GET, params menjadi params kueri. Jadi itu berakhir dalam dua jenis parameter untuk tugas yang sama. Untuk tidak membingungkan pengguna layanan REST dan membatasi upaya untuk pengembang layanan, akan lebih mudah untuk menggunakan selalu kueri params - di area ini.

Karena pengembang layanan dapat memilih kerangka kerja dengan dukungan param matriks, satu-satunya kelemahan yang tersisa adalah browser membuat dengan parameter kueri default.

Apakah ada kerugian lain? Apa yang akan kamu lakukan?

deamon
sumber
10
Saya tidak yakin apa masalahnya dengan URL matriks. Menurut artikel desain w3c yang ditulis TBL, itu hanya ide desain dan secara eksplisit menyatakan bahwa itu bukan fitur web. Hal-hal seperti URL relatif tidak diterapkan ketika menggunakannya. Jika Anda ingin menggunakannya, tidak apa-apa; tidak ada cara standar untuk menggunakannya karena ini bukan standar.
Steve Pomeroy
2
@Steve Pomeroy: Apakah ini artikel yang Anda sebutkan: w3.org/DesignIssues/MatrixURIs.html
Marcel
3
@ Marscel: yup. Bagi mereka yang berpikir tentang URL matriks, perhatikan "Status: tampilan pribadi" di bagian atas dokumen.
Steve Pomeroy
bisakah matriks params memiliki lebih dari satu nilai? Betulkah?
Ayyash

Jawaban:

212

Perbedaan penting adalah bahwa parameter matriks berlaku untuk elemen jalur tertentu sementara parameter kueri berlaku untuk permintaan secara keseluruhan. Ini mulai berlaku saat membuat kueri gaya REST yang rumit ke berbagai tingkat sumber daya dan sub-sumber daya:

http://example.com/res/categories;name=foo/objects;name=green/?page=1

Itu benar-benar turun ke namespacing.

Catatan: 'level' sumber daya di sini adalah categoriesdan objects.

Jika hanya parameter kueri yang digunakan untuk URL multi-level, Anda akan berakhir dengan

http://example.com/res?categories_name=foo&objects_name=green&page=1

Dengan cara ini Anda juga akan kehilangan kejelasan yang ditambahkan oleh lokalitas parameter dalam permintaan. Selain itu, saat menggunakan kerangka kerja seperti JAX-RS, semua parameter kueri akan muncul di setiap penangan sumber daya, yang mengarah ke potensi konflik dan kebingungan.

Jika kueri Anda hanya memiliki satu "level", maka perbedaannya tidak terlalu penting dan kedua jenis parameter ini dapat dipertukarkan secara efektif, namun, parameter kueri umumnya didukung lebih baik dan lebih dikenal luas. Secara umum, saya akan merekomendasikan Anda tetap dengan parameter kueri untuk hal-hal seperti formulir HTML dan API HTTP tingkat tunggal yang sederhana.

Tim Sylvester
sumber
2
tidak relevan: apakah /?bagian mewakili sumber daya?
Jin Kwon
7
The ?dimulai parameter permintaan bagian dari permintaan. Parameter kueri adalah tipe paling umum dari parameter URL, berlawanan dengan parameter matriks. Garis miring sebelum tanda tanya memastikan bahwa parameter kueri pagetidak mengalami parameter matriks yang mendahului garis miring. Saya kira jika tidak ada parameter matriks yang dilampirkan categories, parameter kueri dapat dilampirkan tanpa garis miring seperti ini:http://example.com/res/categories?page=1
Teemu Leisti
8
Meskipun benar bahwa parameter matriks dapat ditentukan dalam segmen jalur apa pun, JAX-RS misalnya tidak mengaitkannya dengan segmen jalur tempat mereka ditambahkan ketika menyuntikkan dengan @MatrixParam. Menurut "Restful Java with JAX-RS 2.0", permintaan seperti "GET / mercedes / e55; warna = hitam / 2006 / interior; warna = tan" akan memiliki definisi ambigu dari parameter matriks warna. Meskipun sepertinya jika Anda memproses setiap PathSegment secara individual, Anda dapat mengetahuinya ... Sangat berguna tetapi lebih banyak pekerjaan untuk mencapainya daripada jika Anda menentukan categoryName = foo; objectName = green.
UFL1138
15

Selain jawaban Tim Sylvester, saya ingin memberikan contoh bagaimana parameter matriks dapat ditangani dengan JAX-RS .

  1. Parameter matriks pada elemen sumber daya terakhir

    http://localhost:8080/res/categories/objects;name=green

    Anda dapat mengaksesnya menggunakan @MatrixParamanotasi

    @GET
    @Path("categories/objects")
    public String objects(@MatrixParam("name") String objectName) {
      return objectName;
    }
    

    Tanggapan

    green

    Tetapi seperti negara-negara Javadoc

    Perhatikan bahwa nilai @MatrixParamanotasi mengacu pada nama parameter matriks yang berada di segmen jalur yang cocok terakhir dari struktur Java Path-annotated yang menyuntikkan nilai parameter matriks.

    ... apa yang membawa kita ke poin 2

  2. Parameter matriks di tengah URL

    http://localhost:8080/res/categories;name=foo/objects;name=green

    Anda dapat mengakses parameter matriks di mana saja menggunakan variabel jalur dan @PathParam PathSegment.

    @GET
    @Path("{categoryVar:categories}/objects")
    public String objectsByCategory(@PathParam("categoryVar") PathSegment categorySegment, 
                                    @MatrixParam("name") String objectName) {
      MultivaluedMap<String, String> matrixParameters = categorySegment.getMatrixParameters();
      String categorySegmentPath = categorySegment.getPath();
      String string = String.format("object %s, path:%s, matrixParams:%s%n", objectName,
              categorySegmentPath, matrixParameters);
      return string;
    }
    

    Tanggapan

    object green, path:categories, matrixParams:[name=foo]

    Karena parameter matriks disediakan sebagai MultivaluedMapAnda dapat mengakses masing-masing oleh

    List<String> names = matrixParameters.get("name");

    atau jika Anda hanya membutuhkan yang pertama

    String name = matrixParameters.getFirst("name");
  3. Dapatkan semua parameter matriks sebagai satu parameter metode

    http://localhost:8080/res/categories;name=foo/objects;name=green//attributes;name=size

    Gunakan List<PathSegment>untuk mendapatkan semuanya

    @GET
    @Path("all/{var:.+}")
    public String allSegments(@PathParam("var") List<PathSegment> pathSegments) {
      StringBuilder sb =  new StringBuilder();
    
      for (PathSegment pathSegment : pathSegments) {
        sb.append("path: ");
        sb.append(pathSegment.getPath());
        sb.append(", matrix parameters ");
        sb.append(pathSegment.getMatrixParameters());
        sb.append("<br/>");
      }
    
      return sb.toString();
    }
    

    Tanggapan

    path: categories, matrix parameters [name=foo]
    path: objects, matrix parameters [name=green]
    path: attributes, matrix parameters [name=size]
    
René Link
sumber
10

--Terlalu penting untuk dipindahkan ke bagian komentar .--

Saya tidak yakin apa masalahnya dengan URL matriks. Menurut artikel desain w3c yang ditulis TBL, itu hanya ide desain dan secara eksplisit menyatakan bahwa itu bukan fitur web. Hal-hal seperti URL relatif tidak diterapkan ketika menggunakannya. Jika Anda ingin menggunakannya, tidak apa-apa; tidak ada cara standar untuk menggunakannya karena ini bukan standar. - Steve Pomeroy

Jadi jawaban singkatnya adalah, jika Anda membutuhkan RS untuk tujuan bisnis, Anda lebih baik menggunakan parameter permintaan.

Ajeet Ganga
sumber
5
Seseorang mengatakan itu kepada pengembang Angular 2 yang memutuskan mereka begitu unik sehingga mereka perlu menerapkan ini!
Matt Pileggi
2
@MattPileggi Saya juga membaca ini karena Angular 2. Hampir setiap aspek dari Angular 2 sangat khusus, tidak konvensional, dan bertentangan dengan pola penggunaan yang ada. Sampai sekarang belum terbukti bahwa ini menambah nilai mitigasi.
Aluan Haddad
1
Jadi teman-teman, saya di sini juga untuk alasan yang sama, tetapi izinkan saya menambahkan beberapa poin untuk diskusi ini dengan masalah ini tentang url matrix dan google analytis pada halaman github tim 2 sudut: github.com/angular/angular/issues/11740 Tapi setelah beberapa penelitian tentang hal itu, notasi matriks url tampaknya lebih dapat dibaca manusia daripada parameter permintaan url , terutama ketika kita membutuhkan beberapa parameter di tengah atau url (tidak hanya di akhir itu).
Richard Lee
8
Saya kira semua orang yang berpikir ini non-standar juga tidak akrab dengan spesifikasi template uri? Pengkodean objek kompleks dalam params jalur adalah fitur yang sangat berguna dari template uri; hanya karena kebanyakan orang tidak tahu atau menggunakannya bukan berarti itu adalah konspirasi jahat oleh devs sudut untuk menyuntikkan kompleksitas yang tidak berguna ke dalam hidup Anda.
Ajax
2
Pffft - "<sesuatu yang saya tidak tahu ada sampai sekarang> adalah non-standar sehingga menjaga penerimaan ketidaktahuan saya". Apa yang TBL lakukan atau tidak putuskan untuk lakukan dengan suatu gagasan sebagian besar tidak material. Itu bukan fitur web- nya pada tahun 2001. Fitur web adalah apa pun yang dipilih oleh klien dan pelaksana server. Jika Angular mendukung params matriks dan JAX-RS mendukungnya dan ini adalah alat implementasi yang Anda pilih, silakan gunakan apa yang berfungsi.
Dave