Home » Difference between @RequestParam and @PathVariable

Difference between @RequestParam and @PathVariable

Difference between @RequestParam and @PathVariable

1. Overview

In this article, we will learn the difference between @RequestParam and @PathVariable.

Before going to the topic, let’s understand a few basic terminologies:

1.1. URI

A resource identifier that uniquely identifies a specific resource. A URI contains scheme, authority, path, query, and a fragment. The syntax of URI:

scheme:[//authority]path[?query][#fragment]  

1.2. URI path

The URI always contains a sequence of path segments separated by a slash(/). However, the path may be empty or of 0 lengths.

GET /orders

1.3. URI Path param.

You got all pets using the GET /orders URI. Consider you want to get a specific pet using its order id. Then you can use URI path param.

GET /orders/11

1.4. URI query param

A URI can optionally contain a query param which helps to sort or filter the resources. It can support hierarchical and non-hierarchical URI. A question mark (?) precedes it. The aforementioned GET /orders/11 returns the pet with order id 11. What if you want to filter orders using their date or other attributes? Here, the query param comes in handy.

For example, the below URI contains the query param date. This basically filters the orders resources using the date.

GET /orders?since=2021-11-21

Now, we know the basic concepts. Let’s understand the differences between @RequestParam and @PathParam.

2. Parameter mapping difference between @RequestParam and @PathVariable

2.1. @RequestParam

The @RequestParam annotation binds the request parameters to a method parameter in your controller.

For example, the below getOrders handler method of the Orders controller handles all the incoming HTTP GET requests with path /orders. The request param maps the query param since to the method parameter sinceDate.

@RestController
public class OrdersController {

    Logger logger = (Logger) LoggerFactory.getLogger(OrdersController.class);

    @GetMapping("/orders")
    public String getOrders(@RequestParam(name = "since", required = false) String since) {
        logger.debug("Orders since " + since);
        return "Orders since: " + since;
    }
}

When you hit the URI http://localhost:8080/orders?since=2021-10-21, then the above getOrders function filters the order created after the date Oct 21st, 2021.

By default, @RequestParam requires query parameters to be present in the URI. However, you can make it optional by setting @RequestParam‘s required attribute to false. In the above example, the since query param is optional: @RequestParam(value="since", required=false)).

The @RequestParam annotation supports the following parameters:

  • defaultValue: Default value as a fallback mechanism when the request doesn’t have a value or is empty.
  • name: Name of the query parameter to bind
  • required: Whether the parameter is mandatory. By default, it is true.
  • value: An alternative alias for the name attribute

2.2. @PathVariable

On the other hand, @PathVariable identifies the placeholder or template variable that is used in the URI for the incoming request.

For example, the below code matches the orderId placeholder or template variable in the URI to the method parameter orderId.

@GetMapping("/orders/{orderId}")
public String getOrdersById(@PathVariable long orderId) {
    logger.debug("order id " + orderId);
    return "Order " + orderId;
}

The @PathVariable annotation supports the following parameters:

  • name: Name of the path placeholder to bind
  • required: Whether the parameter is mandatory. By default, it is true.
  • value: An alternative alias for the name attribute
@PathVariable

In the below code, the orderId path variable is optional. The same function accepts URI GET /orders and also GET /order/{orderId}.

@GetMapping(value = {"/orders", "/orders/{orderId}"})
    public String getOrdersById(@PathVariable(required = false) Integer orderId) {
        logger.debug("order id " + orderId);
        return "Order " + orderId;
}

2.3. Combine in a single handler method

You can combine both @RequestParam and @PathVariable in a single method handler as below:

@GetMapping(value = {"/orders", "/orders/{orderId}"})
    public String getOrdersById(@RequestParam(name = "since", required = false) String since, 
    		@PathVariable(required = false) Integer orderId) {
        logger.debug("order id " + orderId);
        return "Order " + orderId + " since: " + since;
}

3. Conclusion

To sum up, we understood the basics of URI. Post that, we have seen the differences between @PathVariable and @RequestParam. You can refer to our articles to know more about Spring.

Leave a Reply

Your email address will not be published. Required fields are marked *