Spring @GetMapping, @PostMapping, @PutMapping, @DeleteMapping and @PatchMapping

In this article, we will discuss Spring 4.3. introduced HTTP method-specific shortcut variants of @RequestMapping are @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, and @PatchMapping annotations with sample code examples.

New Spring MVC Request Annotations

Typically, if we want to implement the URL handler using traditional @RequestMapping annotation, it would have been something like this:
@RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
The new approach makes it possible to shorten this simply to:
@GetMapping("/get/{id}")
Spring currently supports five types of inbuilt annotations for handling different types of incoming HTTP request methods which are GET, POST, PUT, DELETE, and PATCH. These annotations are:
  1. @GetMapping - shortcut for @RequestMapping(method = RequestMethod.GET)
  2. @PostMapping - shortcut for @RequestMapping(method = RequestMethod.POST)
  3. @PutMapping - shortcut for @RequestMapping(method = RequestMethod.PUT)
  4. @DeleteMapping - shortcut for @RequestMapping(method =RequestMethod.DELETE)
  5. @PatchMapping - shortcut for @RequestMapping(method = RequestMethod.PATCH)
From the naming convention, we can see that each annotation is meant to handle the respective incoming request method type, i.e. @GetMapping is used to handle the GET type of request method, @PostMapping is used to handle POST type of request method, etc.

How It Works

All of the above annotations are already internally annotated with @RequestMapping and the respective value in the method element.
For example, if we’ll look at the source code of @GetMapping annotation, we can see that it’s already annotated with RequestMethod.GET in the following way:
@Target({ java.lang.annotation.ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = { RequestMethod.GET })
public @interface GetMapping {
    // abstract codes
}
All the other annotations are created in the same way, i.e. @PostMapping is annotated with RequestMethod.POST, @PutMapping is annotated with RequestMethod.PUT, etc.

Add Maven Dependency

Let’s try to use these annotations to build a quick REST application.
Please note that since we would use maven to build the project and Spring MVC to create our application, we need to add necessary dependencies in the pom.xml:
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.1.2.RELEASE</version>
</dependency>
Let's discuss each annotation with an example.

@GetMapping

The GET HTTP request is used to get a single or multiple resources and @GetMapping annotation for mapping HTTP GET requests onto specific handler methods.
Specifically, @GetMapping is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.GET).
Example:
@GetMapping("/employees")
public List<Employee> getAllEmployees() {
    return employeeRepository.findAll();
}

@GetMapping("/employees/{id}")
public ResponseEntity<Employee> getEmployeeById(@PathVariable(value = "id") Long employeeId)
 throws ResourceNotFoundException {
    Employee employee = employeeRepository.findById(employeeId)
      .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));
    return ResponseEntity.ok().body(employee);
}

@PostMapping

The POST HTTP method is used to create a resource and @PostMapping annotation for mapping HTTP POST requests onto specific handler methods.
Specifically, @PostMapping is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.POST).
Example:
@PostMapping("/employees")
public Employee createEmployee(@Valid @RequestBody Employee employee) {
    return employeeRepository.save(employee);
}

@PutMapping

The PUT HTTP method is used to update the resource and @PutMapping annotation for mapping HTTP PUT requests onto specific handler methods.
Specifically, @PutMapping is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.PUT).
Example:
@PutMapping("/employees/{id}")
public ResponseEntity<Employee> updateEmployee(@PathVariable(value = "id") Long employeeId,
  @Valid @RequestBody Employee employeeDetails) throws ResourceNotFoundException {
    Employee employee = employeeRepository.findById(employeeId)
    .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));

    employee.setEmailId(employeeDetails.getEmailId());
    employee.setLastName(employeeDetails.getLastName());
    employee.setFirstName(employeeDetails.getFirstName());
    final Employee updatedEmployee = employeeRepository.save(employee);
    return ResponseEntity.ok(updatedEmployee);
}

@DeleteMapping

The DELETE HTTP method is used to delete the resource and @DeleteMapping annotation for mapping HTTP DELETE requests onto specific handler methods.
Specifically, @DeleteMapping is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.DELETE).
Example:
@DeleteMapping("/employees/{id}")
public Map<String, Boolean> deleteEmployee(@PathVariable(value = "id") Long employeeId)
  throws ResourceNotFoundException {
    Employee employee = employeeRepository.findById(employeeId)
      .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));

    employeeRepository.delete(employee);
    Map<String, Boolean> response = new HashMap<>();
    response.put("deleted", Boolean.TRUE);
    return response;
}

@PatchMapping

The PATCH HTTP method is used when you want to apply a partial update to the resource and @PatchMapping annotation for mapping HTTP PATCH requests onto specific handler methods.
Specifically, @PatchMapping is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.PATCH).
Example: Consider we want to update the Employee resources partially (only firstName field) in a database. So here is the REST API that demonstrates the usage of @PatchMapping annotation:
@PatchMapping("/employees/{id}/{firstName}")
public ResponseEntity<Employee> updateEmployeePartially(@PathVariable Long id, @PathVariable String firstName) {
	try {
		Employee employee = employeeRepository.findById(id).get();
employee.setFirstName(firstName); return new ResponseEntity<Employee>(employeeRepository.save(employee), HttpStatus.OK); } catch (Exception e) { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } }

Complete Example - EmployeeController.java

@RestController
@RequestMapping("/api/v1")
public class EmployeeController {
    @Autowired
    private EmployeeRepository employeeRepository;

    @GetMapping("/employees")
    public List<Employee> getAllEmployees() {
        return employeeRepository.findAll();
    }

    @GetMapping("/employees/{id}")
    public ResponseEntity<Employee> getEmployeeById(@PathVariable(value = "id") Long employeeId)
        throws ResourceNotFoundException {
        Employee employee = employeeRepository.findById(employeeId)
          .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));
        return ResponseEntity.ok().body(employee);
    }
    
    @PostMapping("/employees")
    public Employee createEmployee(@Valid @RequestBody Employee employee) {
        return employeeRepository.save(employee);
    }

    @PutMapping("/employees/{id}")
    public ResponseEntity<Employee> updateEmployee(@PathVariable(value = "id") Long employeeId,
         @Valid @RequestBody Employee employeeDetails) throws ResourceNotFoundException {
        Employee employee = employeeRepository.findById(employeeId)
        .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));

        employee.setEmailId(employeeDetails.getEmailId());
        employee.setLastName(employeeDetails.getLastName());
        employee.setFirstName(employeeDetails.getFirstName());
        final Employee updatedEmployee = employeeRepository.save(employee);
        return ResponseEntity.ok(updatedEmployee);
    }

    @DeleteMapping("/employees/{id}")
    public Map<String, Boolean> deleteEmployee(@PathVariable(value = "id") Long employeeId)
         throws ResourceNotFoundException {
        Employee employee = employeeRepository.findById(employeeId)
       .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));

        employeeRepository.delete(employee);
        Map<String, Boolean> response = new HashMap<>();
        response.put("deleted", Boolean.TRUE);
        return response;
    }
    
    @PatchMapping("/employees/{id}/{firstName}")
    public ResponseEntity<Employee> updateEmployeePartially(@PathVariable Long id, @PathVariable String firstName) {
	try {
		Employee employee = employeeRepository.findById(id).get();
		employee.setFirstName(firstName);
		return new ResponseEntity<Employee>(employeeRepository.save(employee), HttpStatus.OK);
	} catch (Exception e) {
		return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
	}
    }
}
Refer this article for complete CRUD example at https://www.javaguides.net/2018/09/spring-boot-2-jpa-mysql-crud-example.html

Related Annotations 

Comments

  1. You not include the PatchMapping in the Complete example, sad

    ReplyDelete

Post a Comment