Tham số ma trận URL so với tham số truy vấn


176

Tôi đang tự hỏi nên sử dụng ma trận hoặc tham số truy vấn trong URL của mình. Tôi tìm thấy một cuộc thảo luận cũ hơn cho chủ đề đó không thỏa mãn.

Ví dụ

Thoạt nhìn ma trận params dường như chỉ có lợi thế:

  • dễ đọc hơn
  • không yêu cầu mã hóa và giải mã "&" trong tài liệu XML
  • URL có "?" không được lưu trữ trong nhiều trường hợp; Các URL có tham số ma trận được lưu trữ
  • tham số ma trận có thể xuất hiện ở mọi nơi trong đường dẫn và không giới hạn ở phần cuối của nó
  • tham số ma trận có thể có nhiều hơn một giá trị: paramA=val1,val2

Nhưng cũng có những nhược điểm:

  • chỉ một vài khung như tham số ma trận hỗ trợ JAX-RS
  • Khi trình duyệt gửi biểu mẫu qua GET, thông số sẽ trở thành thông số truy vấn. Vì vậy, nó kết thúc trong hai loại tham số cho cùng một nhiệm vụ. Để không gây nhầm lẫn cho người dùng dịch vụ REST và hạn chế nỗ lực cho các nhà phát triển dịch vụ, sẽ dễ dàng hơn khi sử dụng luôn truy vấn params - trong lĩnh vực này.

Vì nhà phát triển dịch vụ có thể chọn một khung có hỗ trợ ma trận param, nên nhược điểm duy nhất còn lại là các trình duyệt được tạo bởi các tham số truy vấn mặc định.

Có bất kỳ nhược điểm nào khác không? Bạn sẽ làm gì?


10
Tôi không chắc vấn đề lớn với URL ma trận là gì. Theo bài viết thiết kế w3c mà TBL đã viết, đó chỉ là một ý tưởng thiết kế và tuyên bố rõ ràng rằng đó không phải là một tính năng của web. Những thứ như URL tương đối không được triển khai khi sử dụng nó. Nếu bạn muốn sử dụng nó, điều đó tốt; không có cách tiêu chuẩn nào để sử dụng nó vì nó không phải là một tiêu chuẩn.
Steve Pomeroy

2
@Steve Pomeroy: Đây có phải là bài viết bạn đề cập: w3.org/DesignIssues/MatrixURIs.html
Marcel

3
@Marcel: yup. Đối với những người suy nghĩ về URL ma trận, hãy lưu ý "Trạng thái: chế độ xem cá nhân" ở đầu tài liệu.
Steve Pomeroy

tham số ma trận có thể có nhiều hơn một giá trị? có thật không?
Ayyash

Câu trả lời:


212

Sự khác biệt quan trọng là các tham số ma trận áp dụng cho một phần tử đường dẫn cụ thể trong khi các tham số truy vấn áp dụng cho toàn bộ yêu cầu. Điều này phát huy tác dụng khi thực hiện một truy vấn kiểu REST phức tạp tới nhiều cấp tài nguyên và tài nguyên phụ:

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

Nó thực sự đi xuống không gian tên.

Lưu ý: 'cấp độ' tài nguyên ở đây là categoriesobjects.

Nếu chỉ các tham số truy vấn được sử dụng cho URL đa cấp, bạn sẽ kết thúc bằng

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

Bằng cách này, bạn cũng sẽ mất đi sự rõ ràng được thêm vào bởi địa phương của các tham số trong yêu cầu. Ngoài ra, khi sử dụng một khung như JAX-RS, tất cả các tham số truy vấn sẽ hiển thị trong mỗi trình xử lý tài nguyên, dẫn đến xung đột và nhầm lẫn tiềm ẩn.

Nếu truy vấn của bạn chỉ có một "cấp độ", thì sự khác biệt không thực sự quan trọng và hai loại tham số có thể thay thế cho nhau một cách hiệu quả, tuy nhiên, các tham số truy vấn thường được hỗ trợ tốt hơn và được công nhận rộng rãi hơn. Nói chung, tôi khuyên bạn nên gắn bó với các tham số truy vấn cho những thứ như biểu mẫu HTML và API HTTP đơn cấp, đơn giản.


2
không liên quan: /?một phần đại diện cho một tài nguyên?
Jin Kwon

7
Việc ?bắt đầu phần tham số truy vấn của yêu cầu. Tham số truy vấn là loại tham số URL phổ biến nhất, trái ngược với tham số ma trận. Dấu gạch chéo trước dấu chấm hỏi đảm bảo rằng tham số truy vấn pagekhông chạy vào tham số ma trận đi trước dấu gạch chéo. Tôi cho rằng nếu không có tham số ma trận nào được đính kèm categories, các tham số truy vấn có thể được đính kèm mà không có dấu gạch chéo như sau:http://example.com/res/categories?page=1
Teemu Leisti

8
Mặc dù đúng là các tham số ma trận có thể được chỉ định trong bất kỳ phân đoạn đường dẫn nào, ví dụ, JAX-RS không liên kết chúng với phân đoạn đường dẫn mà chúng được gắn vào khi tiêm @MatrixParam. Theo "Restful Java with JAX-RS 2.0", một yêu cầu như "GET / mercedes / e55; color = black / 2006 / nội thất; color = tan" sẽ có một định nghĩa mơ hồ về tham số ma trận màu. Mặc dù có vẻ như nếu bạn xử lý từng PathSegment riêng lẻ, bạn có thể tìm ra nó ... Rất hữu ích nhưng cần nhiều công việc hơn nếu bạn chỉ định categoryName = foo; objectName = green.
UFL1138

15

Ngoài câu trả lời của Tim Sylvester, tôi muốn cung cấp một ví dụ về cách xử lý các tham số ma trận với JAX-RS .

  1. Các tham số ma trận ở phần tử tài nguyên cuối cùng

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

    Bạn có thể truy cập chúng bằng cách sử dụng @MatrixParamchú thích

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

    Phản ứng

    green

    Nhưng giống như các quốc gia Javadoc

    Lưu ý rằng @MatrixParamgiá trị chú thích đề cập đến tên của một tham số ma trận nằm trong phân đoạn đường dẫn phù hợp cuối cùng của cấu trúc Java có chú thích Đường dẫn tiêm giá trị của tham số ma trận.

    ... điều gì đưa chúng ta đến điểm 2

  2. Các tham số ma trận ở giữa một URL

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

    Bạn có thể truy cập các tham số ma trận bất cứ nơi nào bằng cách sử dụng các biến đường dẫn và @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;
    }
    

    Phản ứng

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

    Vì các tham số ma trận được cung cấp dưới dạng MultivaluedMapbạn có thể truy cập từng

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

    hoặc nếu bạn chỉ cần cái đầu tiên

    String name = matrixParameters.getFirst("name");
  3. Nhận tất cả các tham số ma trận làm một tham số phương thức

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

    Sử dụng một List<PathSegment>để có được tất cả

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

    Phản ứng

    path: categories, matrix parameters [name=foo]
    path: objects, matrix parameters [name=green]
    path: attributes, matrix parameters [name=size]
    

10

--Too quan trọng để được xuống hạng để bình luận .--

Tôi không chắc vấn đề lớn với URL ma trận là gì. Theo bài viết thiết kế w3c mà TBL đã viết, đó chỉ là một ý tưởng thiết kế và tuyên bố rõ ràng rằng đó không phải là một tính năng của web. Những thứ như URL tương đối không được triển khai khi sử dụng nó. Nếu bạn muốn sử dụng nó, điều đó tốt; không có cách tiêu chuẩn nào để sử dụng nó vì nó không phải là một tiêu chuẩn. - Steve Pomeroy

Vì vậy, câu trả lời ngắn gọn là, nếu bạn cần RS cho mục đích kinh doanh, tốt hơn hết bạn nên sử dụng tham số yêu cầu.


5
Ai đó nói với các nhà phát triển Angular 2, những người quyết định rằng họ rất độc đáo, họ cần phải thực hiện điều này thay vào đó!
Matt Pileggi

2
@MattPileggi Tôi cũng đang đọc bài này vì Angular 2. Hầu như mọi khía cạnh của Angular 2 đều mang tính chuyên môn cao, độc đáo và mâu thuẫn với các kiểu sử dụng hiện có. Như chưa được chứng minh rằng điều này làm tăng giá trị giảm nhẹ.
Aluan Haddad

1
Vì vậy, các bạn, tôi cũng ở đây vì lý do tương tự, nhưng hãy để tôi thêm một số điểm cho vấn đề này với vấn đề này về ma trận url và phân tích google trên trang github của nhóm 2 góc: github.com/angular/angular/issues/11740 Nhưng sau một số nghiên cứu về nó, ký hiệu ma trận url xuất hiện dễ đọc hơn con người so với tham số truy vấn url , chủ yếu là khi chúng ta cần một số tham số ở giữa hoặc url (không chỉ ở cuối của nó).
Richard Lee

8
Tôi đoán tất cả những người nghĩ rằng điều này là không chuẩn cũng không quen thuộc với thông số mẫu uri? Mã hóa các đối tượng phức tạp trong thông số đường dẫn là một tính năng rất hữu ích của các mẫu uri; chỉ bởi vì hầu hết mọi người không biết hoặc sử dụng nó không có nghĩa đó là một âm mưu xấu xa của các nhà phát triển góc cạnh để tiêm phức tạp vô dụng vào cuộc sống của bạn.
Ajax

2
Pffft - "<điều tôi không biết đã tồn tại cho đến bây giờ> là không chuẩn do đó duy trì khả năng chấp nhận sự thiếu hiểu biết của tôi". Những gì TBL đã làm hoặc không quyết định làm với một ý tưởng phần lớn là không quan trọng. Nó không phải là một tính năng của web của anh ấy vào năm 2001. Các tính năng của web là bất cứ điều gì mà người triển khai máy khách và máy chủ chọn chúng. Nếu Angular hỗ trợ các tham số ma trận và JAX-RS hỗ trợ chúng và đây là những công cụ triển khai bạn đã chọn thì hãy tiếp tục và sử dụng những gì hoạt động.
Dave
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.