Introduction
Hello! In our last lesson, we built our first REST controller and mapped GET and POST requests using @GetMapping and @PostMapping. We learned how to define endpoints that could return a static list of items or create a new item from a request body.
Today, we'll make our endpoints much more dynamic and powerful. Your goal for this lesson is to use @PathVariable and @RequestParam to extract data from incoming requests. This is a fundamental skill for building realistic REST APIs, allowing you to create endpoints that can retrieve a specific resource (like a user with ID 123) or filter a collection of resources (like finding all users with an "active" status).
We'll cover the syntax for both annotations and, more importantly, the design principles that guide when to use each one—a topic that ties directly into robust system design.
@PathVariable: Extracting Data from the URL Path
The @PathVariable annotation is used to bind a method parameter to a URI template variable. In simpler terms, it lets you extract values from the URL's path itself. This is the standard way to identify a specific resource in a RESTful API.
Consider a URL for retrieving a specific user: GET /users/101. Here, 101 is the unique identifier for the user. To implement this, you define a placeholder in your mapping path with curly braces {} and use @PathVariable to capture its value.
Let's see this in action. The following article provides a clear, minimal example.
Spring @RequestParam vs @PathVariable Annotations
The article 'Spring @RequestParam vs @PathVariable Annotations' by Baeldung provides a succinct introduction to both annotations. We'll start with its explanation of @PathVariable.
Read the section titled 'Query Parameter vs URI Path'. Focus on the first code block demonstrating @GetMapping("/foos/{id}") and @PathVariable String id. This shows the direct mapping between the URL placeholder and the method parameter.
As you saw in the article, the implementation is straightforward:
@RestController
@RequestMapping("/users")
public class UserController {
// A real implementation would query a database.
@GetMapping("/{id}")
public String getUserById(@PathVariable String id) {
return "Fetching details for user with ID: " + id;
}
}
Key points:
- The placeholder in the path is
{id}. - The
@PathVariableannotation on theidparameter tells Spring to inject the value from that placeholder. - If your method parameter name matches the placeholder name (like
idhere), you can use@PathVariablewithout any arguments. If they differ, you must specify the name:@PathVariable("id") String userId.
@RequestParam: Extracting Data from Query Parameters
The @RequestParam annotation is used to extract data from the query string portion of a URL (the part after the ?). These are typically used for filtering, sorting, or pagination.
For example, in a URL like GET /users?status=active&page=1, status and page are query parameters. You can use @RequestParam to bind their values to method parameters.
@RequestParam is very flexible. Let's look at an article that demonstrates how to define required and optional parameters, as well as provide default values.
Spring Boot - @PathVariable and @RequestParam Annotations
This GeeksforGeeks article, 'Spring Boot - @PathVariable and @RequestParam Annotations', gives a great overview of @RequestParam, including its most useful attributes.
Read the section 'Using @RequestParam'. Pay close attention to the second code block, which shows how to use the required = false and defaultValue attributes. This is a very common pattern.
Here is a consolidated example based on the article's concepts:
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping
public String findUsers(
@RequestParam(value = "status", defaultValue = "all") String status,
@RequestParam(value = "sort", required = false) String sort) {
String response = "Searching for users with status: " + status;
if (sort != null) {
response += " | Sorting by: " + sort;
}
return response;
}
}
Key points:
- A
GETrequest to/users?status=activewould setstatusto"active"andsorttonull. - A
GETrequest to/userswould use the default value, settingstatusto"all". - The
sortparameter is optional becauserequiredis set tofalse. If it's not provided, its value will benull. - The
statusparameter is technically required by default, but since it has adefaultValue, it will never cause an error if omitted.
The following image provides a fantastic visual summary of how both annotations map parts of a URL to your method's parameters.

The Core Difference: When to Use Which?
You can technically pass an ID as a request parameter (e.g., /users?id=101), so how do you decide which to use? The choice is guided by RESTful API design principles. The "Code Decode" video below explains this distinction exceptionally well.
@RequestParam vs @PathVariable Spring boot | Differences | Path variable Request param |Code Decode
This video provides a deep dive into the practical and logical differences between @PathVariable and @RequestParam. We'll focus on the part that explains the design philosophy behind choosing one over the other.
Watch the segment from 03:30 to 07:14. The presenter clearly explains the core principle: @PathVariable is for uniquely and mandatorily identifying a resource, while @RequestParam is for providing additional, often optional, filtering or configuration.
To summarize the video's excellent points:
- Use
@PathVariablefor mandatory identifiers. It's part of the resource's "address". A request to/users/{id}implies that theidis essential to locate the resource. Omitting it doesn't make sense; you'd be requesting a different endpoint (/users). - Use
@RequestParamfor optional data or filters. They modify the representation of the resource or collection but don't change its fundamental identity. Sorting, filtering, and pagination are classic use cases. A request to/usersis valid on its own; adding?status=activesimply refines the result.
A Detailed Comparison
Now that you understand the core design principle, let's compare some of the practical characteristics of these two annotations. This table provides a high-level summary.
Let's elaborate on a few of these points, as they have important practical implications.
1. Handling Multiple Values
@RequestParam makes it trivial to accept multiple values for the same parameter. You can map them directly to a List or an array. This is useful for endpoints where a user can select multiple tags, IDs, or categories.
- URL:
GET /articles?tags=java,spring - Code:
@RequestParam List<String> tags
Doing this with @PathVariable is complex and generally not recommended, as it goes against the principle of identifying a single resource.
2. Ordering
The order of @PathVariables in the URL is critical because they are position-based.
- URL mapping:
GET /organizations/{orgId}/users/{userId} - Code:
@PathVariable String orgId, @PathVariable String userId- Spring maps the first placeholder to the first parameter, the second to the second, and so on. Swapping
orgIdanduserIdin the URL would incorrectly assign the values.
- Spring maps the first placeholder to the first parameter, the second to the second, and so on. Swapping
The order of @RequestParams does not matter because they are identified by their key (name).
?status=active&sort=nameis identical to?sort=name&status=active.
3. URL Structure and Flexibility
Adding a new @RequestParam doesn't change the endpoint's URL mapping. It's a backward-compatible change. Clients who don't know about the new parameter can continue to call the endpoint as they did before.
Adding a new @PathVariable requires changing the URL mapping itself, which is a breaking change for existing clients.
- Changing from
/users/{id}to/users/{id}/{profileType}requires all clients to update their request URLs.
For a deeper look at these practical differences, the same "Code Decode" video offers clear demonstrations.
@RequestParam vs @PathVariable Spring boot | Differences | Path variable Request param |Code Decode
Let's return to the 'Code Decode' video to see demonstrations of handling multiple values, ordering, and URL flexibility.
You may find it useful to watch these specific segments: Handling Multiple Values (10:12 - 12:30): Shows how easily @RequestParam handles a list of values compared to @PathVariable. Flexibility in URL Structure (15:06 - 16:41): Explains why adding a @RequestParam is more flexible than adding a @PathVariable. Ordering (17:53 - 20:22): Clearly demonstrates why order matters for @PathVariable but not for @RequestParam.
Conclusion
In this lesson, you've learned how to make your REST endpoints significantly more capable by extracting dynamic data directly from a request's URL.
Key Takeaways:
@PathVariableextracts values from URI path segments (e.g.,{id}in/users/{id}). It is best used for mandatory identifiers that uniquely locate a resource.@RequestParamextracts values from query parameters (e.g.,statusin/users?status=active). It is ideal for optional filtering, sorting, or pagination criteria.@RequestParamsupports attributes likerequiredanddefaultValueto provide greater flexibility.- The choice between the two is a key API design decision:
@PathVariabledefines what the resource is, while@RequestParamdefines how you want to view it.
In our next lesson, we will shift our focus back to the data payload of a request. We'll take a deeper dive into handling JSON, exploring @RequestBody in more detail and learning how to customize the structure of the JSON response sent back to the client.