This section dives into how to handle different ways of passing data to your Spring Boot REST APIs: using @PathVariable and @RequestParam. These annotations are crucial for building flexible and user-friendly APIs.
Understanding Request Parameters
Before we jump into the code, let's understand why we need these. When a client (like a web browser or another application) makes a request to your API, it often needs to send data along with it. This data can be sent in a few ways:
- As part of the URL: This is common for identifying a specific resource. For example,
/users/123where123is the user ID. - As query parameters: These are appended to the URL after a
?and are used for filtering, sorting, or providing additional information. For example,/products?category=electronics&sort=price.
@PathVariable and @RequestParam help Spring Boot extract this data from the request and make it available to your controller methods.
@PathVariable: Extracting Data from the URL Path
@PathVariable is used to extract values directly from the URL path. It's ideal for identifying specific resources.
Example:
Let's create a simple API endpoint to retrieve a user by their ID.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@GetMapping("/users/{userId}")
public String getUser(@PathVariable("userId") Long userId) {
// In a real application, you'd fetch the user from a database here.
return "User with ID: " + userId;
}
}
Explanation:
@GetMapping("/users/{userId}"): This maps GET requests to the/users/{userId}path. The{userId}part is a placeholder for the user ID.@PathVariable("userId") Long userId: This annotation tells Spring Boot to extract the value from the URL path at the{userId}placeholder and bind it to theuserIdparameter of thegetUsermethod. The"userId"inside the annotation specifies which placeholder to bind to.Longspecifies the expected data type.
How to test it:
If you send a GET request to http://localhost:8080/users/123, the getUser method will be called with userId set to 123. The API will return "User with ID: 123".
Important Considerations:
- Data Type: Ensure the data type of the
@PathVariableparameter matches the expected type in the URL. Spring Boot will attempt to convert the value, and if it fails, it will throw an exception. - Required: By default,
@PathVariableparameters are required. If the placeholder is missing in the URL, Spring Boot will throw an exception. You can make it optional by usingrequired = falsewithin the annotation (e.g.,@PathVariable("userId") Long userId). However, you'll need to handle the case where the parameter is missing in your code.
@RequestParam: Extracting Data from Query Parameters
@RequestParam is used to extract values from query parameters in the URL. It's useful for filtering, sorting, or providing optional information.
Example:
Let's create an API endpoint to retrieve products based on a category.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProductController {
@GetMapping("/products")
public String getProducts(@RequestParam(value = "category", defaultValue = "all") String category) {
// In a real application, you'd fetch products from a database based on the category.
return "Products in category: " + category;
}
}
Explanation:
@GetMapping("/products"): This maps GET requests to the/productspath.@RequestParam(value = "category", defaultValue = "all") String category: This annotation tells Spring Boot to extract the value from the query parameter namedcategoryand bind it to thecategoryparameter of thegetProductsmethod.value = "category": Specifies the name of the query parameter to extract.defaultValue = "all": Provides a default value if thecategoryquery parameter is not present in the request. If the parameter is missing,categorywill be set to "all".
How to test it:
http://localhost:8080/products: The API will return "Products in category: all" (because thecategoryparameter is missing, so the default value is used).http://localhost:8080/products?category=electronics: The API will return "Products in category: electronics".http://localhost:8080/products?category=books&sort=price: The API will return "Products in category: books" (only thecategoryparameter is used in this example).
Important Considerations:
- Data Type: Similar to
@PathVariable, ensure the data type of the@RequestParamparameter matches the expected type in the query string. Spring Boot will attempt to convert the value. - Required: By default,
@RequestParamparameters are optional. If the parameter is missing, the parameter in your method will be set tonull(for object types) or the default value (if specified). You can make a@RequestParamparameter required by settingrequired = truewithin the annotation. If a required parameter is missing, Spring Boot will throw an exception. - Multiple Parameters: You can have multiple
@RequestParamannotations in a single method to extract multiple query parameters.
Combining @PathVariable and @RequestParam
You can use both @PathVariable and @RequestParam in the same controller method to handle both path variables and query parameters.
Example:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ItemController {
@GetMapping("/items/{itemId}")
public String getItemDetails(@PathVariable("itemId") Long itemId, @RequestParam(value = "details", defaultValue = "basic") String details) {
// Fetch item details based on itemId and details level
return "Item ID: " + itemId + ", Details Level: " + details;
}
}
How to test it:
http://localhost:8080/items/456: Returns "Item ID: 456, Details Level: basic"http://localhost:8080/items/456?details=full: Returns "Item ID: 456, Details Level: full"
Summary
@PathVariableextracts data from the URL path. Use it for identifying specific resources.@RequestParamextracts data from query parameters. Use it for filtering, sorting, or providing optional information.- You can combine both annotations in a single method to handle both types of request parameters.
- Pay attention to data types and whether parameters are required or optional. Use
defaultValuefor@RequestParamto provide sensible defaults.
By mastering @PathVariable and @RequestParam, you'll be well-equipped to build robust and flexible REST APIs with Spring Boot.