Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 56

Controller Input: Paths, Queries, and Bodies

Recommended resources

In our last session, we constructed the primary endpoints for our REST API, learning how to map HTTP methods like GET, POST, PUT, and DELETE to our controller. You saw a glimpse of @PathVariable and @RequestBody, which are essential for making our API interactive. Today, we will master the art of handling incoming data by diving deep into these annotations and introducing a new one: @RequestParam.

This lesson is crucial for building robust and flexible APIs. You will learn the distinct roles of path variables, query parameters, and request bodies, enabling you to design endpoints that can handle everything from identifying a specific resource to filtering a large dataset or creating a complex new object. Understanding when and how to use each of these is a fundamental skill for any backend developer.

Three Ways to Receive Data

When a client communicates with your API, it needs a way to send information. Spring Boot provides three primary annotations in a controller to capture this data:

  1. @PathVariable: Extracts values from the URL path itself. Ideal for identifying a specific resource.
  2. @RequestParam: Extracts values from the query string of a URL. Perfect for filtering, sorting, or optional parameters.
  3. @RequestBody: Extracts a complex object (like a JSON payload) from the body of the HTTP request. Used for creating or updating resources.

To get a quick overview of these three mechanisms, let's start with a short article that introduces each one with simple code examples.

Understanding URL Parameters in Spring Boot

This guide by Davoud Badamchi provides a clear, high-level introduction to query parameters (@RequestParam), path variables (@PathVariable), and the request body (@RequestBody).

Read the first three sections, paying attention to the URL structure in each example: Query Parameters: Notice the ? and & symbols. Path Variables: See how the value is part of the main URL path. Request Body: Understand that this data is not in the URL at all.

Now, let's explore each of these in more detail, starting with the two that appear directly in the URL.


@PathVariable vs. @RequestParam: A Detailed Comparison

You've already used @PathVariable to fetch a single employee by their ID (e.g., GET /employees/1). This is its classic use case: when the value is a mandatory identifier for a resource. The URL path itself implies a hierarchy or a specific entity.

@RequestParam, on the other hand, is used for parameters that "qualify" the request, but don't fundamentally change the resource being accessed. They are used for filtering, sorting, or pagination. For example, imagine you want to find all employees who have the role "Developer". The URL would look like this:

GET /api/employees?role=Developer

Here, role=Developer is a query parameter. It filters the list of employees. If you omitted it, you'd simply get all employees. This makes query parameters ideal for optional data.

In your controller, you would handle this with @RequestParam:

@GetMapping("/employees")
public List<Employee> getEmployeesByRole(@RequestParam(required = false) String role) {
    if (role != null) {
        // Logic to find employees by role
        return service.findEmployeesByRole(role);
    } else {
        // Logic to find all employees
        return service.findAllEmployees();
    }
}

Notice the required = false attribute. This tells Spring that the role parameter is optional. If the client doesn't provide it, the role variable will be null. You can also provide a defaultValue.

The following image provides a concise summary of the key differences.

This table clearly outlines the different use cases and characteristics of `@RequestParam` and `@PathVariable`, which are two of the most common annotations for handling URL-based data in Spring Boot.

To see these concepts explained with detailed code examples and practical advice, the following video is an excellent resource. It methodically breaks down the "when" and "why" for choosing one over the other.

@RequestParam vs @PathVariable Spring boot | Differences | Path variable Request param |Code Decode

This video from the "Code Decode" channel provides a thorough comparison, highlighting the conceptual and practical differences between @RequestParam and @PathVariable.

Watch the following segments to solidify your understanding: When to Use What: This part explains the core design principle: use @PathVariable for mandatory, unique identification and @RequestParam for optional filtering criteria. Optional vs. Required: Here, the presenter demonstrates how to make a @RequestParam optional and provide a default value, a key difference from @PathVariable, which is required by default. Ordering and Readability: Watch this segment to understand why the order of parameters doesn't matter for @RequestParam (it uses key-value pairs) but is critical for @PathVariable. This also touches upon human readability.

For those who prefer a textual reference, the Baeldung article below also offers a solid comparison, including how URL encoding is handled differently.

Spring @RequestParam vs @PathVariable Annotations

Baeldung is a highly respected resource in the Java community. This article provides a concise, code-driven comparison.

Focus on these three short sections: Read the first section to see the direct code and URL comparison. In the next section, notice how a + symbol is decoded as a space for @RequestParam but not for @PathVariable. Finally, read the section on making parameters optional.


@RequestBody: Handling Complex Data

While URL parameters are great for simple key-value pairs, they are not suitable for sending complex, structured data. When a client needs to create a new employee or update an existing one, it will send a full data object. This data is placed in the body of the HTTP request, most commonly in JSON format.

You handled this in the previous lesson with @RequestBody. Spring, with the help of a library called Jackson, automatically deserializes the incoming JSON into an instance of your Java class (e.g., your Employee DTO or entity).

This is a typical example of using `@RequestBody`. The client sends a POST request with a JSON object in the request body. The Spring controller method annotated with `@RequestBody` receives this data as a Java object, ready to be processed and saved.

Let's watch a practical demonstration of implementing and testing endpoints that use @PathVariable and @RequestBody. This will connect the theory directly back to the CRUD operations you built in the last lesson.

Spring Boot For Beginners - @PathVariable & @RequestBody

This tutorial by Teddy Smith provides a clear, hands-on walkthrough of building endpoints that use @PathVariable and @RequestBody, complete with Postman testing.

Please watch these key segments: @PathVariable in Action: Watch here as the presenter builds a GET endpoint to fetch a single resource by its ID. Notice how the ID from the URL path is passed into the method. @RequestBody for Creation: This part demonstrates creating a POST endpoint. Pay close attention to how a JSON payload is sent from Postman and mapped to a Java object using @RequestBody. Combining Both for Updates: This segment shows a PUT endpoint, which is a perfect example of using both annotations together: @PathVariable identifies which resource to update, and @RequestBody provides the new data for that resource.


Conclusion

You have now thoroughly explored the three essential ways to handle client data in a Spring Boot RestController. Mastering these annotations is fundamental to designing clean, intuitive, and powerful REST APIs.

Key Takeaways:

  • @PathVariable: Use it to identify a specific resource. The value is a mandatory part of the URL path (e.g., /employees/42).
  • @RequestParam: Use it for optional filtering, sorting, or pagination. The values are key-value pairs in the query string (e.g., /employees?status=active&sort=name_asc). You can make them optional and provide default values.
  • @RequestBody: Use it to receive complex objects, typically as JSON, in the body of POST or PUT requests. It's the standard for creating or updating resources with multiple fields.

In our next lesson, we will move to the persistence layer. Now that you know how to get data into your controller, the next step is to learn how to save that data to a database. We will explore the Java Persistence API (JPA) and see how Spring Data JPA makes database operations incredibly simple and efficient.