In this post, we will focus on Spring Boot RequestMapping annotation. The @RequestMapping annotation is one of the most important annotations when exposing API endpoints using Spring Boot Microservices.

Below is the high-level plan for this post.

  • Understand the basics of @RequestMapping. Look at it on the basis of Path and HTTP method.
  • How can narrow @RequestMapping to our endpoints using specific headers?
  • How does @RequestMapping and path variables work together?
  • Check out how @RequestMapping works with Request Parameters.
  • Also, we will look at the new way to manage @RequestMapping annotation.

After going through this post, you will be fully clear with Spring Boot RequestMapping annotation.

So let’s start.

Basics of Spring Boot RequestMapping Annotation

The simplest example to demonstrate Request Mapping in action to map an end-point to a method.

1. Mapping by Path

In this case, we simply map a path to a method in the controller.

@RequestMapping(value = "/api/by-simple-path")
@ResponseBody
public String getDataFromSimplePath(){
        return "Data from Simple Path";
}

This end-point can be invoked using curl command.

curl -i localhost:8080/api/by-simple-path

2. Mapping using HTTP Method Type

The method type has no default value. So it can work for all the possible HTTP methods such as GET, POST, PUT and so on. However, we can map a method to a particular HTTP Method Type.

@RequestMapping(value = "/api/by-simple-path", method = RequestMethod.POST)
@ResponseBody
public String getDataFromSimplePath(){
        return "Data from Simple Path";
}

The end-point can be invoked as below:

curl -i -X POST http://localhost:8080/api/by-simple-path

Spring Boot RequestMapping with Headers

Headers allow us to narrow down our end-points further. For example, the below end-point can only be called using the header value.

@RequestMapping(value = "/api/path-with-header",
            headers = "key=val",
            method = RequestMethod.GET)
@ResponseBody
public String getDataFromSimplePath(){
        return "Data from Simple Path";
}

Below is how we can call it using curl.

curl -i -H "key:val" http://localhost:8080/api/path-with-header

If we call this endpoint without the header value as below, we will get error.

curl -i http://localhost:8080/api/by-simple-path

The special use of this feature comes in the case of media types.

In other words, we can map a request based on its Accept header using the @RequestMapping headers attribute.

See below code for example.

@RequestMapping(value = "/api/path-with-header",
            headers = "Accept=application/json",
            method = RequestMethod.GET)
@ResponseBody
public String getDataFromSimplePath(){
        return "Data from Simple Path";
}

Here, the Accept header expects a value of application/json. Basically, now this endpoint can be invoked with the below curl command:

curl -H "Accept:application/json, text/html" http://localhost:8080/api/path-with-header

If you notice the matching here is flexible. It basically uses contains instead of equals. Therefore, the value text/html is ignored.

Additionally, we can also use produces and consumes from Spring 3.1 onward.

@RequestMapping(value = "/api/path-with-header",
            produces = {"application/json", "application/xml"},
            method = RequestMethod.GET)
@ResponseBody
public String getDataFromSimplePath(){
        return "Data from Simple Path";
}

It also follows similar rules with regards to contains instead of equals.

Spring Boot RequestMapping with Path Variables

Using path variables, we can also bind parts of the path with a variable value.

1. Single Path Variable

We can have a single path variable as below:

@RequestMapping(value = "/api/path-with-variable/{id}",
            method = RequestMethod.GET)
@ResponseBody
    public String getDataFromSimplePath(@PathVariable String id){
        return "Data from Simple Path Variable: " + id;
}

We can test the above path as below.

curl http://localhost:8080/api/path-with-variable/1

In this case, the value of the path variable id will be accessible in the method.

2. Multiple Path Variables

We can also have multiple path variables in the same endpoint.

@RequestMapping(value = "/api/path-with-multiple-variable/{firstId}/second-variable/{secondId}",
            method = RequestMethod.GET)
@ResponseBody
public String getDataFromSimplePath(@PathVariable("firstId") String firstId,
                                        @PathVariable("secondId") String secondId){
        return "Path Variable first id " + firstId + " and second id " + secondId;
}

Also, we can test it as below:

curl -i http://localhost:8080/api/path-with-multiple-variable/1/second-variable/2

Also, note here we also specify the value of the path variable in the @PathVariable annotation. This is useful when the name of the path variable is different to the name of the method variable.

3. Path Variable with Regex

We can also use Regular Expressions or Regex in path variables. For example, let’s say we want a particular endpoint to only accept numeric value as path variable.

The below endpoint does exactly that using Regex pattern.

@RequestMapping(value = "/api/numeric-path/{id:[\\d]+}",
            method = RequestMethod.GET)
@ResponseBody
    public String getDataFromSimplePath(@PathVariable String id){
        return "Numeric Path Variable is: " + id;
}

This endpoint can be tested using the below curl command.

curl -i http://localhost:8080/api/numeric-path/2

However, the below command will give an error.

curl -i http://localhost:8080/api/numeric-path/abc

RequestMapping using Request Parameters

Yet another feature of RequestMapping is to map the URL parameters with the @RequestParam annotation.

For example, if we wish to pass a query parameter to our endpoint as below:

http://localhost:8080/api/request-param?name="neo"

This can be handled with the below endpoint definition.

@RequestMapping(value = "/api/request-param",
            method = RequestMethod.GET)
@ResponseBody
public String getRequestParamData(@RequestParam("name") String name){
        return "Request Param is: " + name;
}

Here, we extract the value of the name parameter using @RequestParam(“name”) annotation. Basically, we assign the value to a variable name in our method signature.

Mapping Shortcuts for Spring Boot RequestMapping

From Spring 4.3 onward, new annotations have been launched for simplifying the request mappings.

These annotations are @GetMapping, @PostMapping, @PutMapping, @DeleteMapping and @PatchMapping.

Basically, these new annotations help improve readability of the code and reduce the verbosity.

Below is how you can use one of them as an example.

@GetMapping("/api/get-data/{id}")
public String getRequestParamData(@RequestParam String id){
        return "Data Request for Id: " + id;
}

As you can see, this makes our endpoints more compact. Also, on similar lines, you can have endpoints for POST, PUT, DELETE and so on.

Conclusion

In this post, we looked at the various options with @RequestMapping annotation.

Basically, by using these various options, we can design better endpoints. In other words, we can potentially build better and clearer API interfaces for our consumers.

Using this knowledge, we can now look at building RESTful APIs using Spring Boot.

If you have any queries or comments, sound off in the comments section below.

Happy Learning!


Saurabh Dashora

Saurabh is a Software Architect with over 12 years of experience. He has worked on large-scale distributed systems across various domains and organizations. He is also a passionate Technical Writer and loves sharing knowledge in the community.

0 Comments

Leave a Reply

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