@PathVariable
Extracting values from the URL path — URL templates, ConversionService, UUID/enum/date types, multiple variables, name matching, failure cases and @PathVariable vs @RequestParam.
#Introduction
One of the most frequently used annotations in Spring Boot. Most developers know how to write:
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
}But interviewers ask: How does Spring extract id from the URL? What happens if the value is not a number? How does Spring convert String to Long? Can we have multiple path variables? Can UUID, enums and LocalDate be used? What's the difference between @PathVariable and @RequestParam?
#What is @PathVariable?
@PathVariable extracts values from the URL path and binds them to method parameters.
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return service.findById(id);
}
}For GET /users/101, Spring extracts 101 and assigns it to Long id.
#How Does Spring Understand the URL?
Spring stores /users/{id} as a URL template. For an incoming /users/101:
Request Lifecycle
#Internal Working
Conceptually Spring does:
String value = "101";
Long id = Long.valueOf(value);
controller.getUser(id);Of course, Spring uses its conversion infrastructure rather than literally calling Long.valueOf(), but this illustrates the idea.
#Type Conversion
For /users/25, Spring converts "25" → 25L automatically. No parsing required.
Supported Types
@PathVariable Integer id
@PathVariable Long id
@PathVariable UUID id
@PathVariable Double amount
@PathVariable Boolean active
@PathVariable Status status // any enum
@PathVariable LocalDate date // ISO yyyy-MM-dd, or use @DateTimeFormatNo manual parsing is needed if a suitable converter exists.
UUID Example
@GetMapping("/{id}")
public User getUser(@PathVariable UUID id) {
}/users/550e8400-e29b-41d4-a716-446655440000 → Spring converts the string into a UUID.
Enum Example
public enum Status {
ACTIVE,
INACTIVE
}
@GetMapping("/{status}")
public String status(@PathVariable Status status) {
return status.name();
}/users/ACTIVE → Status.ACTIVE.
#Multiple Path Variables
@GetMapping("/{userId}/orders/{orderId}")
public Order getOrder(@PathVariable Long userId,
@PathVariable Long orderId) {
}/users/101/orders/5001 → userId = 101, orderId = 5001.
Nested Resources
@GetMapping("/companies/{companyId}/employees/{employeeId}/projects/{projectId}")
public Project get(@PathVariable Long companyId,
@PathVariable Long employeeId,
@PathVariable Long projectId) {
}/companies/5/employees/101/projects/20 — Spring extracts all three values automatically.
#Path Variable Name Matching
@GetMapping("/{id}")
public User get(@PathVariable Long id) {
}Works because {id} ↔ id — the names match.
Different Variable Names
@GetMapping("/{id}")
public User get(@PathVariable("id") Long userId) {
}Spring maps {id} → userId using the explicit annotation value.
#What If Conversion Fails?
@GetMapping("/{id}")
public User get(@PathVariable Long id) {
}For /users/abc, Spring tries "abc" → Long and fails:
400 Bad Request (MethodArgumentTypeMismatchException)#Missing Path Variable
With only @GetMapping("/{id}"), a request to /users cannot match the route → 404 Not Found, because there is no handler for /users.
#Optional Path Variables?
Many developers ask whether @PathVariable(required = false) is possible. It exists, but it only makes sense when the same method is also mapped to a URL without the variable:
@GetMapping({"", "/{id}"})
public Object get(@PathVariable(required = false) Long id) {
}Usually it's clearer to write separate mappings:
@GetMapping
public List<User> all() {
}
@GetMapping("/{id}")
public User one(@PathVariable Long id) {
}(Optional<Long> is also supported as the parameter type.)
#@PathVariable vs @RequestParam
An extremely common interview question.
// /users/10 — value is part of the URL path
@GetMapping("/{id}")
public User get(@PathVariable Long id) {}
// /users?id=10 — value comes from the query string
@GetMapping
public User get(@RequestParam Long id) {}| Feature | @PathVariable | @RequestParam |
|---|---|---|
| Location | URL path | Query parameter |
| Example | /users/10 | /users?id=10 |
| Required | Usually yes | Configurable |
| Used for | Resource identification | Filtering, sorting, pagination |
REST Best Practice
✅ GET /users/10 — the URL identifies the resource. ❌ GET /getUser?id=10.
#URL Encoding
For /users/John%20Doe, the browser sends John%20Doe and Spring automatically decodes it to John Doe before passing it to the controller.
#Internal Components
PathPatternParser(orAntPathMatcherin older configurations) matches the URL pattern.PathVariableMethodArgumentResolverresolves@PathVariableparameters.ConversionServiceconvertsStringvalues into target Java types.
These names are excellent interview points.
#Common Mistakes
Parsing Manually
// ❌ Wrong
@GetMapping("/{id}")
public User get(@PathVariable String id) {
Long userId = Long.parseLong(id);
}
// ✅ Correct — let Spring handle conversion
@GetMapping("/{id}")
public User get(@PathVariable Long id) {
}Using @RequestParam for Identifiers
Prefer /users/10 over /users?id=10 when the ID uniquely identifies the resource.
Mismatched Variable Names
// ❌ Wrong — there is no {userId} in the template
@GetMapping("/{id}")
public User get(@PathVariable Long userId) {
}Spring looks for a template variable called userId, doesn't find one, and fails (MissingPathVariableException, a 500). Correct: @PathVariable("id") Long userId.
#Enterprise Example
@RestController
@RequestMapping("/employees")
public class EmployeeController {
@GetMapping("/{id}")
public Employee get(@PathVariable Long id) {
return service.findById(id);
}
@DeleteMapping("/{id}")
public void delete(@PathVariable Long id) {
service.delete(id);
}
}GET /employees/101 returns employee 101; DELETE /employees/101 deletes employee 101.
#Interview Questions
Q1What is @PathVariable?
It binds a value from the URL path to a controller method parameter.
Q2Who converts String to Long?
Spring's ConversionService.
Q3Can @PathVariable be Integer, UUID or Enum?
Yes. Spring supports automatic conversion for many common Java types, including Integer, Long, UUID, enums and more.
Q4What happens if conversion fails?
Spring returns 400 Bad Request, because the value can't be converted to the target type.
Q5What is the difference between @PathVariable and @RequestParam?
@PathVariableidentifies a resource as part of the URL path.@RequestParamreads query parameters, often used for filtering, sorting, pagination or optional inputs.
Q6Which internal Spring class resolves @PathVariable?
PathVariableMethodArgumentResolver, which delegates type conversion to the ConversionService.
Q7Can we have multiple path variables?
Yes — e.g. /users/10/orders/100 maps to @GetMapping("/{userId}/orders/{orderId}").
#Summary Diagram
#Key Takeaways
@PathVariablebinds values from the URL path to method parameters.- Spring converts string values using the
ConversionService. - Multiple path variables are fully supported.
- Prefer
@PathVariablefor resource identifiers and@RequestParamfor filters and query options. PathVariableMethodArgumentResolverandConversionServiceare key internal components.- Let Spring perform type conversion instead of parsing values manually.