Spring @PathVariable Annotation

Last Updated : 23 Jun, 2026

The @PathVariable annotation in Spring is used to extract values from the URL path and bind them to method parameters in a controller. It enables developers to create dynamic and RESTful URLs, making applications more flexible and easier to maintain.

  • Extracts dynamic values directly from the URL path.
  • Binds URL path variables to controller method parameters using @PathVariable.
  • Commonly used in RESTful APIs to identify resources such as user IDs, product IDs, or order IDs.

Syntax:

@GetMapping("/users/{userId}")
public String getUser(@PathVariable("userId") String userId) {
return "User ID is: " + userId;
}

Example of Spring @PathVariable Annotation

1. Basic @PathVariable Usage

Java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class UserController {

    @GetMapping("/users/{userId}")
    public String fetchUserById(@PathVariable("userId") Long userId) {
        return "Retrieved User ID: " + userId;
    }
}

Explanation:

  • @RestController: Marks the class as a REST controller and returns data directly in the HTTP response.
  • @RequestMapping("/api"): Sets /api as the base URL for all endpoints.
  • @GetMapping("/users/{userId}"): Maps GET requests to the /users/{userId} endpoint.
  • @PathVariable("userId"): Binds the userId value from the URL to the method parameter.

Output:

For a request to /api/users/123, the output would be: "Retrieved User ID: 123"

2. Handling Optional Path Variables

Java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
@RequestMapping("/api")
public class UserController {

    @GetMapping("/users/{userId}/{userName}")
    public String fetchUserDetails(@PathVariable Map<String, String> pathVariables) {
        String userId = pathVariables.get("userId");
        String userName = pathVariables.get("userName");

        if (userId != null && userName != null) {
            return "User ID: " + userId + ", Name: " + userName;
        } else {
            return "Parameters are missing";
        }
    }
}

Explanation:

  • @PathVariable(name = "postId", required = false): Marks the postId path variable as optional. If postId is not provided in the URL, it will be null.

Expected Output:

  • For a request to /api/users/123/posts/456, the output would be: "User ID: 123 and Post ID: 456"
  • For a request to /api/users/123/posts, the output would be: "User ID: 123 with no post specified."

3. Handling Multiple @PathVariable Parameters

Java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
@RequestMapping("/api")
public class UserController {

    @GetMapping("/users/{userId}/{userName}")
    public String fetchUserDetails(@PathVariable Map<String, String> pathVariables) {
        String userId = pathVariables.get("userId");
        String userName = pathVariables.get("userName");

        if (userId != null && userName != null) {
            return "User ID: " + userId + ", Name: " + userName;
        } else {
            return "Parameters are missing";
        }
    }
}

Explanation:

  • @PathVariable Map<String, String> pathVariables: Binds all path variables to a Map. The keys of the map are the path variable names, and the values are the path variable values.

Expected Output:

  • For a request to /api/users/123/john, the output would be: "User ID: 123, Name: john"
  • For a request with missing parameters, the output would be: "Parameters are missing"

4. Basic Mapping for Class and Method Levels

Java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/users")
public class UserController {

    @GetMapping("/details/{userId}/{userName}")
    public String retrieveUserDetails(@PathVariable("userId") String userId, @PathVariable("userName") String userName) {
        return "ID: " + userId + ", Name: " + userName;
    }
}

Explanation:

  • @RequestMapping("/api/users"): Sets /api/users as the base URL for all endpoints.
  • @GetMapping("/details/{userId}/{userName}"): Maps GET requests to the /details/{userId}/{userName} endpoint.

Expected Output:

For a request to /api/users/details/123/john, the output would be: "ID: 123, Name: john"

5. Including Default Values for Path Variables

Java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class UserController {

    @GetMapping({ "/users/required", "/users/required/{userId}" })
    public String getUserById(@PathVariable(required = false) String userId) {
        if (userId != null && !userId.isEmpty()) {
            return "User ID: " + userId;
        } else {
            return "User ID is missing";
        }
    }
}

Explanation:

  • @PathVariable(required = false): Makes the userId path variable optional. If not provided, a default message is returned.

Expected Output:

  • For a request to /api/users/required/123, the output would be: "User ID: 123"
  • For a request to /api/users/required, the output would be: "User ID is missing"

6. Creating a Default Value for @PathVariable

Java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Optional;

@RestController
@RequestMapping("/api/users")
public class UserController {

    @GetMapping({ "/default/optional", "/default/optional/{id}" })
    public String fetchUserWithOptionalId(@PathVariable Optional<String> id) {
        return id.map(value -> "User ID: " + value)
                 .orElse("User ID: Default User");
    }
}

Explanation:

  • @PathVariable Optional<String> id: Uses Optional to handle the presence or absence of the path variable id. If id is not present, a default value is used.

Expected Output:

  • For a request to /api/users/default/optional/123, the output would be: "User ID: 123"
  • For a request to /api/users/default/optional, the output would be: "User ID: Default User"
Comment

Explore