QueryParam
PathParam
Web Development
Programming
API Design

When to use @QueryParam vs @PathParam

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Use @PathParam when the parameter identifies a specific resource. Use @QueryParam when the parameter filters, sorts, or modifies the response for a collection. The rule is straightforward: if removing the parameter would change which resource you are talking about, it belongs in the path. If removing it would return the same resource with less refinement, it belongs in the query string.

java
1// PathParam: the userId identifies a specific resource
2@GET
3@Path("/users/{userId}")
4public Response getUser(@PathParam("userId") long userId) { ... }
5
6// QueryParam: status filters the user collection
7@GET
8@Path("/users")
9public Response getUsers(@QueryParam("status") String status) { ... }

Path Parameters: Resource Identity

Path parameters are part of the URL path itself. They define the hierarchical structure of your API and identify specific resources or sub-resources. In REST, every resource has a unique URI, and path parameters are what make that URI unique.

java
1@Path("/organizations/{orgId}/teams/{teamId}/members/{memberId}")
2public class MemberResource {
3
4    @GET
5    public Response getMember(
6        @PathParam("orgId") long orgId,
7        @PathParam("teamId") long teamId,
8        @PathParam("memberId") long memberId
9    ) {
10        // Each parameter narrows to a specific resource
11        return Response.ok(memberService.find(orgId, teamId, memberId)).build();
12    }
13}

The URL /organizations/5/teams/12/members/42 unambiguously identifies one member. Remove any segment and you are talking about a different resource (the team, the organization, or the collection of members).

Characteristics of Path Parameters

  • They are required. Omitting a path segment results in a different URL that routes to a different endpoint or a 404.
  • They represent hierarchy. Each segment narrows the scope from broad (organization) to specific (member).
  • They are positional. The order matters and is defined by the URL template.
  • They contribute to cacheability. Proxies and CDNs cache responses by URL, and path-based URLs produce clean cache keys.

Query Parameters: Filtering and Modification

Query parameters appear after the ? in the URL. They modify how the server processes the request without changing which resource is being addressed.

java
1@Path("/products")
2public class ProductResource {
3
4    @GET
5    public Response searchProducts(
6        @QueryParam("category") String category,
7        @QueryParam("minPrice") @DefaultValue("0") double minPrice,
8        @QueryParam("maxPrice") @DefaultValue("999999") double maxPrice,
9        @QueryParam("sort") @DefaultValue("name") String sort,
10        @QueryParam("page") @DefaultValue("1") int page,
11        @QueryParam("size") @DefaultValue("20") int size
12    ) {
13        // All parameters filter or paginate the same /products resource
14        return Response.ok(productService.search(category, minPrice, maxPrice, sort, page, size)).build();
15    }
16}

The URL /products?category=electronics&sort=price&page=2 still addresses the products collection. The query parameters narrow and shape the result set.

Characteristics of Query Parameters

  • They are optional. Omitting them returns a default or unfiltered response.
  • They support default values via @DefaultValue.
  • They can accept multiple values for the same key (?tag=java&tag=spring).
  • They are not part of the resource identity. Two URLs that differ only in query parameters address the same resource.

Decision Framework

Use this decision tree when designing an endpoint:

QuestionPath if YesQuery if Yes
Does the parameter identify a resource?Yes
Is the parameter required for routing?Yes
Does removing it change the resource?Yes
Is the parameter optional?Yes
Does it filter a collection?Yes
Does it paginate or sort results?Yes
Does it have a sensible default?Yes

Real-World URL Design

 
1# Path params: resource identification
2GET /users/42                      -> specific user
3GET /users/42/orders/7             -> specific order for a specific user
4GET /repos/facebook/react          -> specific repo (org + name)
5
6# Query params: filtering, sorting, pagination
7GET /users?role=admin              -> users filtered by role
8GET /users/42/orders?status=shipped -> orders filtered by status
9GET /products?sort=price&order=asc -> sorted product listing
10GET /articles?page=3&size=25       -> paginated articles

Combining Path and Query Parameters

Most production APIs use both. Path parameters establish which resource or collection you are addressing, and query parameters refine the response:

java
1@Path("/users/{userId}/orders")
2public class OrderResource {
3
4    @GET
5    public Response getUserOrders(
6        @PathParam("userId") long userId,
7        @QueryParam("status") String status,
8        @QueryParam("from") String fromDate,
9        @QueryParam("to") String toDate,
10        @QueryParam("page") @DefaultValue("1") int page
11    ) {
12        // userId (path) identifies whose orders
13        // status, date range, page (query) filter the collection
14        return Response.ok(orderService.findOrders(userId, status, fromDate, toDate, page)).build();
15    }
16}

Spring MVC Equivalents

In Spring MVC, the same concepts apply with different annotations:

java
1@RestController
2@RequestMapping("/api/users")
3public class UserController {
4
5    // Path variable (same role as @PathParam)
6    @GetMapping("/{id}")
7    public User getUser(@PathVariable("id") long id) {
8        return userService.findById(id);
9    }
10
11    // Request parameter (same role as @QueryParam)
12    @GetMapping
13    public List<User> searchUsers(
14        @RequestParam(value = "name", required = false) String name,
15        @RequestParam(value = "page", defaultValue = "0") int page
16    ) {
17        return userService.search(name, page);
18    }
19}
JAX-RSSpring MVCPurpose
@PathParam@PathVariableExtract from URL path
@QueryParam@RequestParamExtract from query string
@DefaultValuedefaultValue attributeSet fallback value

HTTP Method Interactions

The choice between path and query parameters also depends on the HTTP method:

java
1// GET with path param: fetch a specific resource
2@GET @Path("/users/{id}")
3public Response getUser(@PathParam("id") long id) { ... }
4
5// DELETE with path param: delete a specific resource
6@DELETE @Path("/users/{id}")
7public Response deleteUser(@PathParam("id") long id) { ... }
8
9// GET with query params: search/filter a collection
10@GET @Path("/users")
11public Response searchUsers(@QueryParam("name") String name) { ... }
12
13// POST: body contains data, path identifies the collection
14@POST @Path("/users")
15public Response createUser(UserDTO user) { ... }
16
17// PUT with path param: update a specific resource
18@PUT @Path("/users/{id}")
19public Response updateUser(@PathParam("id") long id, UserDTO user) { ... }

For POST and PUT, the request body carries the payload. Query parameters on write operations are uncommon and usually limited to control flags like ?dryRun=true.

Common Pitfalls

Using query parameters for resource identification. Designing /users?id=42 instead of /users/42 breaks REST conventions. The resource should be identifiable by its URL path alone. Query parameters on a GET that returns a single resource is a code smell.

Putting optional filters in the path. A URL like /users/admin/active/page/3 encodes filters as path segments, making the URL rigid and hard to extend. Adding a new filter requires a new path template. Query parameters (/users?role=admin&status=active&page=3) are more flexible and can be added without changing the routing.

Forgetting @DefaultValue on query parameters. Without a default, omitting a query parameter passes null (for objects) or zero (for primitives) into your method. Always specify @DefaultValue for optional parameters to avoid null-handling bugs.

Encoding issues in path parameters. Path parameters containing slashes, dots, or special characters can conflict with URL routing. A username like john.doe may be interpreted as a file extension. Use regex constraints in your path template ({username: [a-zA-Z0-9_]+}) or encode the value.

Over-nesting path parameters. URLs like /a/{aId}/b/{bId}/c/{cId}/d/{dId} become unwieldy. If the nesting goes beyond three levels, consider whether the deep resource can be addressed directly (/d/{dId}) with the parent relationship expressed in the response body instead.

Using @QueryParam for sensitive data. Query parameters appear in server logs, browser history, and referrer headers. Never pass passwords, tokens, or personally identifiable information as query parameters. Use headers or the request body instead.

Summary

  • @PathParam identifies a resource and is part of the URL structure. It is required and positional.
  • @QueryParam filters, sorts, or paginates a response. It is optional and supports default values.
  • Use path parameters for hierarchical resource identification (/users/{id}/orders/{orderId}).
  • Use query parameters for collection modifiers (?status=active&sort=date&page=2).
  • In Spring MVC, the equivalents are @PathVariable and @RequestParam.
  • Avoid putting optional filters in the path, and never pass sensitive data in query strings.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.