Khi nào nên sử dụng @QueryParam so với @PathParam


276

Tôi không hỏi câu hỏi đã được hỏi ở đây: sự khác biệt giữa @PathParam và @QueryParam là gì

Đây là một "thực tiễn tốt nhất" hoặc câu hỏi quy ước.

Khi bạn sẽ sử dụng @PathParamvs @QueryParam.

Những gì tôi có thể nghĩ về quyết định đó có thể là sử dụng cả hai để phân biệt mẫu thông tin. Hãy để tôi minh họa bên dưới LTPO của tôi - ít hơn quan sát hoàn hảo.

Việc sử dụng PathParam có thể được dành riêng cho danh mục thông tin, sẽ rơi vào một nhánh của cây thông tin. PathParam có thể được sử dụng để đi sâu vào phân cấp lớp thực thể.

Trong khi đó, QueryParam có thể được dành riêng để chỉ định các thuộc tính để định vị thể hiện của một lớp.

Ví dụ,

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

/category?instance

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

đấu với /category/instance

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

đấu với ?category+instance

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

Tôi không nghĩ rằng có một quy ước tiêu chuẩn để làm điều đó. Lanhung? Tuy nhiên, tôi muốn nghe về cách mọi người sử dụng PathParam vs QueryParam để phân biệt thông tin của họ như tôi đã nêu ở trên. Tôi cũng rất thích nghe lý do đằng sau việc thực hành.


Câu trả lời:


245

REST có thể không phải là một tiêu chuẩn như vậy, nhưng đọc tài liệu chung về REST và các bài đăng trên blog sẽ cung cấp cho bạn một số hướng dẫn về cách tốt để cấu trúc URL API. Hầu hết các API còn lại có xu hướng chỉ có tên tài nguyên và ID tài nguyên trong đường dẫn. Nhu la:

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

Một số API REST sử dụng chuỗi truy vấn để lọc, phân trang và sắp xếp, nhưng vì REST không phải là một tiêu chuẩn nghiêm ngặt, tôi khuyên bạn nên kiểm tra một số API REST ngoài đó như githubstackoverflow và xem những gì có thể hoạt động tốt cho trường hợp sử dụng của bạn.

Tôi khuyên bạn nên đặt bất kỳ tham số bắt buộc nào trong đường dẫn và bất kỳ tham số tùy chọn nào chắc chắn phải là tham số chuỗi truy vấn. Đặt các tham số tùy chọn trong đường dẫn sẽ trở nên thực sự lộn xộn khi cố gắng viết các trình xử lý URL khớp với các kết hợp khác nhau.


73
" Tôi khuyên bạn nên đặt bất kỳ tham số bắt buộc nào trong đường dẫn và bất kỳ tham số tùy chọn nào chắc chắn phải là tham số chuỗi truy vấn. " - bật ngón tay cái lên +1 có def
smeeb

1
nên quy ước này cũng được sử dụng cho yêu cầu Đặt, giả sử chúng tôi muốn cập nhật một phiên bản cụ thể của thực thể db, nếu URI PUT /depatments/{dept}/employees/{id}/{version}và phiên bản là tùy chọn hoặc nên là PUT /depatments/{dept}/employees/{id}?version=12phiên bản và là tùy chọn
chúc tốt nhất

Trong trường hợp này, tôi muốn giới thiệu: - PUT /depatments/{dept}/employees/{id}/versions/{version}để tạo một nhân viên với phiên bản đã chọn - POST /depatments/{dept}/employees/{id}/versionsđể tạo một nhân viên với phiên bản được xác định bởi phụ trợ
Guillaume Vauvert

90

Đây là những gì tôi làm.

Nếu có một kịch bản để truy xuất một bản ghi dựa trên id, ví dụ bạn cần lấy thông tin chi tiết về nhân viên có id là 15, thì bạn có thể có tài nguyên với @PathParam.

GET /employee/{id}

Nếu có một kịch bản mà bạn cần lấy thông tin chi tiết của tất cả nhân viên nhưng chỉ có 10 người một lúc, bạn có thể sử dụng truy vấn param

GET /employee?start=1&size=10

Điều này nói rằng bắt đầu id nhân viên 1 nhận được mười hồ sơ.

Để tóm tắt, hãy sử dụng @PathParam để truy xuất dựa trên id. Người dùng @QueryParam cho bộ lọc hoặc nếu bạn có bất kỳ danh sách tùy chọn cố định nào mà người dùng có thể vượt qua.


cả '@PathParam' và '@QueryParam' có cung cấp cùng chức năng không? Có phải '@QueryParam' chỉ là một cách viết khác?
Rishabh Agarwal

1
@RishabhAgarwal mặc dù cả hai đều cung cấp cùng chức năng, nhưng thực tế mã sạch là, nên đặt tham số bắt buộc là biến đường dẫn và bất kỳ tham số tùy chọn nào làm tham số truy vấn.
Akhil Ghatiki

@RishabhAgarwal Để biết thêm thông tin, bạn có thể tham khảo bài viết của tôi về phần còn lại Thực hành tốt nhất API
Arun B Chandrasekaran

43

Tôi nghĩ rằng nếu tham số xác định một thực thể cụ thể, bạn nên sử dụng biến đường dẫn. Ví dụ, để có được tất cả các bài đăng trên blog của tôi, tôi yêu cầu

GET: myserver.com/myblog/posts

để có được bài đăng với id = 123, tôi sẽ yêu cầu

GET: myserver.com/myblog/posts/123

nhưng để lọc danh sách bài viết của tôi và nhận tất cả các bài đăng kể từ ngày 1 tháng 1 năm 2013, tôi sẽ yêu cầu

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

Trong ví dụ đầu tiên "bài viết" xác định một thực thể cụ thể (toàn bộ bộ sưu tập các bài đăng trên blog). Trong ví dụ thứ hai, "123" cũng đại diện cho một thực thể cụ thể (một bài đăng trên blog). Nhưng trong ví dụ trước, tham số "kể từ = 2013-01-01" là một yêu cầu để lọc bộ sưu tập bài viết không phải là một thực thể cụ thể. Phân trang và đặt hàng sẽ là một ví dụ tốt, tức là

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

Mong rằng sẽ giúp. :-)


8

Cá nhân tôi đã sử dụng cách tiếp cận "nếu nó có ý nghĩa đối với người dùng để đánh dấu một URL trong đó bao gồm các tham số này thì hãy sử dụng PathParam".

Ví dụ: nếu URL cho hồ sơ người dùng bao gồm một số tham số id hồ sơ, vì điều này có thể được đánh dấu bởi người dùng và / hoặc gửi qua email, tôi sẽ đưa id hồ sơ đó làm tham số đường dẫn. Ngoài ra, một điều đáng lưu ý khác là trang được biểu thị bằng URL bao gồm đường dẫn param không thay đổi - người dùng sẽ thiết lập hồ sơ của mình, lưu nó và sau đó không thể thay đổi nhiều từ đó; điều này có nghĩa là webcrawlers / công cụ tìm kiếm / trình duyệt / vv có thể lưu trữ trang này độc đáo dựa trên đường dẫn.

Nếu một tham số được truyền trong URL có khả năng thay đổi bố cục / nội dung trang thì tôi sẽ sử dụng tham số đó làm truy vấn. Ví dụ: nếu URL hồ sơ hỗ trợ một tham số chỉ định có hiển thị email người dùng hay không, tôi sẽ coi đó là tham số truy vấn. (Tôi biết, có thể nói, bạn có thể nói rằng &noemail=1hoặc bất kỳ tham số nào nó có thể được sử dụng như một tham số đường dẫn và tạo 2 trang riêng biệt - một trang có email trên đó, một trang không có - nhưng về mặt logic thì không vẫn là cùng một trang có hoặc không có các thuộc tính nhất định được hiển thị.

Hy vọng điều này sẽ giúp - tôi đánh giá cao lời giải thích có thể hơi mờ :)


Tôi nghĩ rằng câu trả lời này nhầm lẫn tài nguyên với các tuyến đường. Câu hỏi là về các tài nguyên của API REST, thường trả về JSON hoặc XML, chứ không phải về các tuyến của ứng dụng web, giúp bạn điều hướng trong ứng dụng.
Hampus


5

Đó là một câu hỏi rất thú vị.

Bạn có thể sử dụng cả hai, không có bất kỳ quy tắc nghiêm ngặt nào về chủ đề này, nhưng sử dụng các biến đường dẫn URI có một số lợi thế:

  • Bộ nhớ cache : Hầu hết các dịch vụ bộ đệm web trên internet không lưu bộ đệm yêu cầu NHẬN khi chúng chứa các tham số truy vấn. Họ làm điều đó bởi vì có rất nhiều hệ thống RPC sử dụng các yêu cầu GET để thay đổi dữ liệu trong máy chủ (thất bại !! Nhận phải là một phương pháp an toàn)

Nhưng nếu bạn sử dụng các biến đường dẫn, tất cả các dịch vụ này có thể lưu trữ các yêu cầu GET của bạn.

  • Phân cấp : Các biến đường dẫn có thể biểu thị phân cấp: / Thành phố / Đường / Địa điểm

Nó cung cấp cho người dùng nhiều thông tin hơn về cấu trúc của dữ liệu.

Nhưng nếu dữ liệu của bạn không có bất kỳ mối quan hệ phân cấp nào, bạn vẫn có thể sử dụng các biến Đường dẫn, sử dụng dấu phẩy hoặc dấu chấm phẩy:

/ Thành phố / kinh độ, vĩ độ

Theo quy tắc, sử dụng dấu phẩy khi thứ tự của các tham số có vấn đề, sử dụng dấu chấm phẩy khi thứ tự không quan trọng:

/ IconGenerator / đỏ; xanh dương, xanh lá cây

Ngoài những lý do đó, có một số trường hợp khi sử dụng biến chuỗi truy vấn rất phổ biến:

  • Khi bạn cần trình duyệt tự động đặt các biến dạng HTML vào URI
  • Khi bạn đang làm việc với thuật toán. Ví dụ: công cụ google sử dụng chuỗi truy vấn:

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

Tóm lại, không có bất kỳ lý do mạnh mẽ nào để sử dụng một trong các phương pháp này mà bất cứ khi nào bạn có thể, hãy sử dụng các biến URI.


2

Như đã lưu ý, REST không phải là một tiêu chuẩn. Tuy nhiên, nếu bạn đang tìm cách thực hiện quy ước URI dựa trên tiêu chuẩn, bạn có thể xem xét quy ước URI oData . Ver 4 đã được phê duyệt là một tiêu chuẩn OASIS và các thư viện tồn tại cho oData cho các ngôn ngữ khác nhau bao gồm cả Java thông qua Apache Olingo . Đừng để sự thật là Microsoft sinh ra bạn vì nó đã nhận được sự hỗ trợ từ những người chơi trong ngành khác , bao gồm Red Hat, Citrix, IBM, Blackberry, Drupal, Netflix Facebook và SAP

Thêm người áp dụng được liệt kê ở đây


2

Từ Wikipedia: Bộ định vị tài nguyên thống nhất

Một đường dẫn , chứa dữ liệu, thường được tổ chức ở dạng phân cấp , xuất hiện dưới dạng một chuỗi các phân đoạn được phân tách bằng dấu gạch chéo.

Một truy vấn tùy chọn , được phân tách từ phần trước bằng dấu chấm hỏi (?), Chứa chuỗi truy vấn của dữ liệu không phân cấp .

- Theo thiết kế khái niệm của URL, chúng tôi có thể triển khai PathParam cho các thành phần dữ liệu / chỉ thị / định vị phân cấp hoặc triển khai QueryParam khi dữ liệu không được phân cấp. Điều này có ý nghĩa bởi vì các đường dẫn được sắp xếp tự nhiên, trong khi các truy vấn chứa các biến có thể được sắp xếp tùy ý (các cặp biến / giá trị không được sắp xếp).

Một bình luận trước đó đã viết,

Tôi nghĩ rằng nếu tham số xác định một thực thể cụ thể, bạn nên sử dụng biến đường dẫn.

Một người khác viết,

Sử dụng @PathParam để truy xuất dựa trên id. Người dùng @QueryParam cho bộ lọc hoặc nếu bạn có bất kỳ danh sách tùy chọn cố định nào mà người dùng có thể vượt qua.

Khác,

Tôi khuyên bạn nên đặt bất kỳ tham số bắt buộc nào trong đường dẫn và bất kỳ tham số tùy chọn nào chắc chắn phải là tham số chuỗi truy vấn.

- Tuy nhiên, người ta có thể thực hiện một hệ thống linh hoạt, không phân cấp để xác định các thực thể cụ thể! Một người có thể có nhiều chỉ mục duy nhất trên một bảng SQL và cho phép các thực thể được xác định bằng cách sử dụng bất kỳ tổ hợp trường nào có chứa một chỉ mục duy nhất! Các kết hợp khác nhau (có lẽ cũng được sắp xếp khác nhau), có thể được sử dụng cho các liên kết từ các thực thể khác nhau (người giới thiệu). Trong trường hợp này, chúng tôi có thể xử lý dữ liệu không phân cấp, được sử dụng để xác định các thực thể riêng lẻ - hoặc trong các trường hợp khác, chỉ có thể chỉ định các biến / trường nhất định - các thành phần nhất định của chỉ mục duy nhất - và truy xuất danh sách / bộ bản ghi. Trong những trường hợp như vậy, việc triển khai các URL dưới dạng QueryParams có thể dễ dàng hơn, hợp lý và hợp lý hơn!

Một chuỗi thập lục phân dài có thể làm loãng / giảm giá trị của các từ khóa trong phần còn lại của đường dẫn không? Có thể đáng để xem xét ý nghĩa SEO tiềm năng của việc đặt các biến / giá trị trong đường dẫn hoặc trong truy vấnvà ý nghĩa giao diện con người về việc chúng tôi có muốn người dùng có thể duyệt / khám phá phân cấp URL bằng cách chỉnh sửa nội dung của thanh địa chỉ hay không. Trang 404 Không tìm thấy của tôi sử dụng các biến SSI để tự động chuyển hướng các URL bị hỏng sang cha mẹ của chúng! Robot tìm kiếm cũng có thể đi qua hệ thống phân cấp đường dẫn. Mặt khác, cá nhân tôi, khi tôi chia sẻ URL trên phương tiện truyền thông xã hội, tôi đã loại bỏ thủ công bất kỳ số nhận dạng duy nhất riêng tư nào - thông thường bằng cách cắt ngắn truy vấn khỏi URL, chỉ để lại đường dẫn: trong trường hợp này, có một số tiện ích trong việc đặt số nhận dạng duy nhất trong đường dẫn chứ không phải trong truy vấn. Cho dù chúng tôi muốn tạo điều kiện cho việc sử dụng các thành phần đường dẫn như một giao diện người dùng thô, có lẽ phụ thuộc vào việc dữ liệu / thành phần có thể đọc được bằng con người hay không. Câu hỏi về khả năng đọc của con người liên quan phần nào đến câu hỏi về thứ bậc: thường, dữ liệu có thể được biểu thị dưới dạng từ khóa có thể đọc được của con người cũng được phân cấp; trong khi dữ liệu phân cấp thường có thể được biểu thị dưới dạng từ khóa có thể đọc được. (Bản thân các công cụ tìm kiếm có thể được định nghĩa là tăng cường sử dụng URL làm giao diện người dùng.) Phân cấp từ khóa hoặc chỉ thị có thể không được sắp xếp nghiêm ngặt, nhưng chúng thường đủ gần để chúng ta có thể bao quát các trường hợp thay thế trong đường dẫn vànhãn một tùy chọn là trường hợp "chính tắc" .

Về cơ bản, có một số loại câu hỏi mà chúng tôi có thể trả lời bằng URL cho mỗi yêu cầu:

  1. Những loại hồ sơ / điều chúng tôi đang yêu cầu / phục vụ?
  2. Chúng ta quan tâm đến cái nào?
  3. Làm thế nào để chúng tôi muốn trình bày thông tin / hồ sơ?

Q1 gần như chắc chắn được bảo vệ tốt nhất bởi đường dẫn hoặc PathParams. Q3 (có thể được điều khiển thông qua một tập hợp các tham số tùy chọn và giá trị mặc định được đặt tùy ý); gần như chắc chắn được bao phủ tốt nhất bởi QueryParams. Q2: Nó phụ thuộc vào VÒNG


2

Bạn có thể hỗ trợ cả tham số truy vấn và tham số đường dẫn, ví dụ: trong trường hợp tổng hợp tài nguyên - khi việc thu thập tài nguyên phụ có ý nghĩa riêng.

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

Các tham số truy vấn có thể hỗ trợ tập hợp con phân cấp và không phân cấp; tham số đường dẫn chỉ phân cấp.

Tài nguyên có thể thể hiện nhiều hệ thống phân cấp. Hỗ trợ các đường dẫn ngắn nếu bạn sẽ truy vấn các bộ sưu tập phụ rộng vượt qua các ranh giới phân cấp.

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

Sử dụng các tham số truy vấn để kết hợp phân cấp trực giao.

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

Chỉ sử dụng các tham số đường dẫn trong trường hợp thành phần - khi một tài nguyên không có nghĩa là tách khỏi cha mẹ của nó và bộ sưu tập toàn cầu của tất cả trẻ em không phải là một tài nguyên hữu ích.

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

1

Lý do thực sự rất đơn giản. Khi sử dụng tham số truy vấn, bạn có thể nhập các ký tự như "/" và ứng dụng khách của bạn không cần mã hóa html. Có những lý do khác nhưng đó là một ví dụ đơn giản. Khi nào nên sử dụng một biến đường dẫn. Tôi sẽ nói bất cứ khi nào bạn đang xử lý id hoặc nếu biến đường dẫn là một hướng cho truy vấn.


1

Tôi sẽ đưa ra một biểu hiện cho dấu gạch dưới khi chúng ta sử dụng @Queryparam@pathparam

Ví dụ tôi đang lấy một carResourcelớp là lớp

Nếu bạn muốn làm cho các đầu vào của phương thức resouce của bạn điều khiển thì hãy sử dụng kiểu param như @pathaparam, nếu đầu vào của phương thức tài nguyên của bạn là tùy chọn thì hãy giữ kiểu param đó là @QueryParamparam

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

Đối với điều này, hãy vượt qua yêu cầu

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

Nếu bạn cung cấp req như thế này, resouce sẽ cung cấp cho mô hình và màu xe dựa trên

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

Nếu bạn cung cấp req như thế này, phương thức resoce sẽ chỉ hiển thị xe dựa trên mô hình swift

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

Nếu bạn đưa ra như thế này, chúng tôi sẽ nhận được ngoại lệ ResourceNotFound vì trong lớp phục hồi xe tôi đã khai báo carmodel vì @pathPramđó là bạn phải và nên đưa carmodel là reQ uri nếu không nó sẽ không chuyển req để tái tạo nhưng nếu bạn không chuyển màu Ngoài ra, nó sẽ chuyển req vào tài nguyên tại sao vì màu sắc @quetyParamlà tùy chọn trong req.


0
  1. @QueryParam có thể được sử dụng thuận tiện với chú thích Giá trị mặc định để bạn có thể tránh ngoại lệ con trỏ null nếu không có tham số truy vấn nào được thông qua.

Khi bạn muốn phân tích các tham số truy vấn từ một yêu cầu GET, bạn chỉ cần xác định tham số tương ứng cho phương thức sẽ xử lý yêu cầu GET và chú thích chúng với @QueryParamchú thích

  1. @PathParamtrích xuất các giá trị URI và khớp với @Path. Và do đó có được tham số đầu vào. 2.1 @PathParamcó thể nhiều hơn một và được đặt thành các đối số phương thức

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

Trong ví dụ trên
http://localhost:8080/Restr/rest/msg/{p0}/{p1},
p0trận đấu param1p1trận đấu param2. Vì vậy, đối với URI
http://localhost:8080/Restr/rest/msg/4/6,
chúng tôi nhận được kết quả 10.

Trong Dịch vụ REST, JAX-RS cung cấp @QueryParam@FormParamcả hai để chấp nhận dữ liệu từ yêu cầu HTTP. Một hình thức HTTP có thể được gửi bằng các phương thức khác nhau như GET và POST.

@QueryParam : Chấp nhận yêu cầu GET và đọc dữ liệu từ chuỗi truy vấn.

@FormParam: Chấp nhận yêu cầu POST và tìm nạp dữ liệu từ biểu mẫu HTML hoặc bất kỳ yêu cầu nào của phương tiện truyền thông


0

Trong vỏ quả hạch,

@Pathparam hoạt động cho giá trị chuyển qua cả Tài nguyên và Chuỗi truy vấn

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

@Queryparam chỉ hoạt động với giá trị chuyển qua Chuỗi truy vấn

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