Open In App

Spring @PathVariable Annotation

Last Updated : 09 Aug, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

The @PathVariable annotation in Spring Framework extracts values from URI templates in HTTP requests. It enables dynamic path segments in URLs to be mapped to method parameters in controller methods. This article demonstrates using @PathVariable effectively in a Spring Boot application, focusing on the User entity.

@PathVariable Annotation

The @PathVariable annotation binds a method parameter to a path variable in the URL. This is particularly useful for creating RESTful web services where parts of the URL can be dynamically specified.

Basic Syntax:

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

In this example, {userId} in the URL is mapped to the userId parameter in the method.

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, combining @Controller and @ResponseBody, meaning that the return values of methods will be written directly to the HTTP response body.
  • @RequestMapping("/api"): Sets the base URL for all endpoints in this controller to /api.
  • @GetMapping("/users/{userId}"): Maps HTTP GET requests with /users/{userId} to the fetchUserById method.
  • @PathVariable("userId"): Binds the {userId} path variable from the URL to the userId method parameter.

Expected Output:

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

Note: To know how test the APIs using Postman Tool, refer to this article: Testing REST API with Postman

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 the base URL for all endpoints in this controller to /api/users.
  • @GetMapping("/details/{userId}/{userName}"): Maps HTTP GET requests with /details/{userId}/{userName} to the retrieveUserDetails method.

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"

Conclusion

This article provides a comprehensive overview of the @PathVariable annotation, complete with explanations and expected output for each code example, specifically designed for managing User entities.


Next Article

Similar Reads