Switch to:
6 ways to pass parameters to a REST API in Spring Boot (Java)

6 ways to pass parameters to a REST API in Spring Boot (Java)

Accepting parameters for server-side processing is a fundamental requirement of REST APIs.

Often confusion is made between the different ways of passing parameters, using them incorrectly. This article aims to clarify once and for all the differences between these approaches and explain how to use them correctly in Spring Boot.

We will explore 6 ways to pass parameters to a REST endpoint and how we can accept and read them in Spring Boot with Java.

1. Query Parameters

Query parameters are added to the URL after the question mark.

They are commonly used for filtering, sorting or to provide additional context to the REST endpoint. Their use is simple and immediate, but it is important to be aware of their limitations.

Query parameters are easy to use and readable, ideal for predictable requests and for passing optional data. However, they can be problematic if they contain sensitive data, since these can be exposed in server logs or browser history. Furthermore, some browsers and servers impose limits on URL length, making it difficult to pass very extensive parameters.

// Example – Retrieval of products by category

Let’s imagine we want to get all products belonging to a certain category.


// Endpoint definition
@GetMapping("/products")
public List<Product> getProductsByCategory(@RequestParam String category) {
  return productService.findByCategory(category);
}

// Access to the Endpoint
curl http://localhost:8080/products?category=electronics

2. Path Variables

Path variables are placeholders in the URI that are replaced with real values at the time of the request.

They are perfect for unique identifiers, such as product ID or username, ensuring clear and descriptive URLs. However, they are not suitable for optional parameters, since their absence could invalidate the request.

Using path variables makes APIs more readable and structured, but improper use, such as nesting too many levels of path with parameters, can lead to complex and difficult to manage URLs.

// Example – Retrieval of a specific product

We want to get the information on a specific product given its ID.


// Endpoint definition
@GetMapping("/products/{id}")
public Product getProductById(@PathVariable Long id) {
  return productService.findById(id);
}

// Access to the Endpoint
curl http://localhost:8080/products/101

3. Matrix Variables

Matrix variables allow passing parameters within the URI, separated by a semicolon.

They are useful for applications that require a hierarchical structure of resources, offering an orderly way to filter data directly in the URL. However, they are poorly supported by browsers and some HTTP clients, and require additional configuration in Spring Boot.

If well used, matrix variables improve the readability and flexibility of REST APIs, but their scarce diffusion makes them less practical than other methods.

// Example – Advanced product filtering

We want to filter products by category and maximum price.


// Endpoint definition
@GetMapping("/products")
public List<Product> getFilteredProducts(@MatrixVariable String category, @MatrixVariable double maxPrice) {
  return productService.findByCategoryAndPrice(category, maxPrice);
}

// Access to the Endpoint
curl http://localhost:8080/products;category=electronics;maxPrice=500.00;

4. Request Body

The request body is the ideal approach for sending complex payloads to POST or PUT endpoints.

It allows transmitting structured objects without length limitations, unlike query parameters. However, it is not idempotent: each call can modify the server state, making it unsuitable for read-only operations.

Using the request body is essential for creating and updating resources, but its non-transparent nature can make debugging and data tracking more difficult.

// Example – Creation of new products

We want to add one or more products via a POST request.


// Endpoint definition
@PostMapping("/products/add")
public ResponseEntity<String> addProducts(@RequestBody List<Product> products) {
  productService.addProducts(products);
  return ResponseEntity.ok("Products added successfully");
}

// Access to the Endpoint
curl --header "Content-Type: application/json" \
 --request POST \
 --data '[{"name": "Laptop","category": "electronics","price": 1200.00}, {"name": "Smartphone","category": "electronics","price": 800.00}]' \
 http://localhost:8080/products/add

5. Request Headers

HTTP headers allow passing additional information such as authentication tokens or configuration preferences. This method is useful for transmitting sensitive data securely, avoiding exposing it in the URL.

However, parameters in request headers are not directly visible, making debugging and request management more difficult. Furthermore, some network configurations or proxies can alter or block certain headers.

// Example – Retrieval of a product with authentication

We want to get a specific product but require an authentication token in the header.


// Endpoint definition
@GetMapping("/products/{id}")
public Product getProductById(@PathVariable Long id, @RequestHeader("Authorization") String authToken) {
  return productService.findByIdWithAuth(id, authToken);
}

// Access to the Endpoint
curl -H "Authorization: Bearer <_authToken_>" http://localhost:8080/products/101

6. Cookies

The use of cookies is an effective solution to maintain state between successive requests, for example to track user sessions or save preferences.

Being separate from the URL, cookies offer greater security than query parameters. However, they are subject to restrictions in modern browsers for privacy reasons and can be blocked by some security configurations.

Using cookies in a stateless REST API is not always recommended, since it could go against the principle of request independence. However, for applications that require stateful interactions, they can represent an effective solution.

// Example – Retrieval of products based on user preference

We want to get the recommended products for the user based on their preferences saved in a cookie.


// Endpoint definition
@GetMapping("/products/recommended")
public List<Product> getRecommendedProducts(@CookieValue("UserPreference") String userPreference) {
  return productService.findRecommended(userPreference);
}

// Access to the Endpoint
curl --cookie "UserPreference=gaming" http://localhost:8080/products/recommended

We have explored 6 ways to pass parameters to REST endpoints in Spring Boot and how to access them.

Each method has advantages and limitations, and the choice of the right approach depends on the specific needs of the project.

Correct use of these mechanisms improves the security, readability and maintainability of APIs.