You will be redirect to our new portal geekmonks.com in 10, Happy Learning. Click here to redirect now.

Rest Controller

👉 Develop and Expoe API over HTTP

Updated on: 28 Oct 2024 - Vivek Singh


☕ Spring Rest Contoller [v3.4.0]


📚 Table of Contents


🌐 REST Service Support and Development

Developing RESTful services in Spring Boot is made simple using the spring-boot-starter-web dependency.

  • This starter bundles key components like Spring MVC and an embedded Tomcat server, allowing you to quickly define @RestController classes.
  • The primary goal of a well-designed POST endpoint is to create a new resource and inform the client of its new location. This adheres to the HATEOAS (Hypermedia as the Engine of Application State) principle.
  • It is focused on a specific, valuable pattern in Spring Boot REST service development: returning a response with a link to a newly created resource using the 201 Created status and the Location header.

🛠️ Required Maven Dependency

The core functionality for creating REST services and handling the response entity is provided by the spring-boot-starter-web.

Maven / External Dependency

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

🚀 Sample REST Service Code: 201 Created

When a resource is successfully created via a POST request, the standard HTTP status code is 201 Created. Best practice dictates including a Location header in the response, pointing to the newly created resource’s URI.

Code Changes: UserResource.java

We utilize ServletUriComponentsBuilder to easily construct the new resource’s URI based on the current request’s context.

// language: java
import java.net.URI;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

@RestController
public class UserResource {

    // ... UserDaoService and Logger Autowire / initialization ...

    /**
     * Creates a new User and returns a 201 Created status
     * with the new resource's URI in the Location header.
     */
    @PostMapping("/users")
    public ResponseEntity<User> createUser(@RequestBody User user) {

        // 1. Save the new resource
        logger.debug("User to save : {}", user);
        User savedUser = userDaoService.save(user);

        // 2. Build URL to the new Resource using the current request's context
        // e.g., POST http://localhost:8080/users -> URI: http://localhost:8080/users/{id}
        URI location = ServletUriComponentsBuilder.fromCurrentRequest()
            .path("/{id}") // Append the path segment
            .buildAndExpand(savedUser.getId()) // Replaces {id} with the actual ID
            .toUri();
    
        // 3. Wrap new URL and response object in ResponseEntity
        // ResponseEntity.created(location) sets the HTTP status to 201 and the Location header
        return ResponseEntity.created(location).body(savedUser);
    }
}


Project Reference:


⚙️ Other HTTP Verbs in REST Controllers

Spring REST Controllers use specific annotations to map handler methods to different HTTP verbs (methods) and URIs. This structure is fundamental to RESTful design.

Example Controller for All Methods

// language: java
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ItemResource {

    // 1. GET: Retrieve a resource or a collection
    @GetMapping("/items")
    public List<Item> retrieveAllItems() {
        return itemDaoService.findAll(); // Returns a list (200 OK)
    }

    // 2. GET: Retrieve a specific resource
    @GetMapping("/items/{id}")
    public Item retrieveItem(@PathVariable int id) {
        return itemDaoService.findOne(id); // Returns the Item (200 OK)
    }

    // 3. POST: Create a new resource (as discussed)
    @PostMapping("/items")
    public ResponseEntity<Item> createItem(@RequestBody Item item) {
        // ... logic for 201 Created ...
        return ResponseEntity.created(location).body(item);
    }

    // 4. PUT: Update an existing resource (full replacement)
    @PutMapping("/items/{id}")
    public ResponseEntity<Item> updateItem(@PathVariable int id, @RequestBody Item itemDetails) {
        // Update logic...
        return ResponseEntity.ok(updatedItem); // 200 OK
    }

    // 5. PATCH: Partially update an existing resource (partial modification)
    @PatchMapping("/items/{id}")
    public ResponseEntity<Item> patchItem(@PathVariable int id, @RequestBody Item itemPatch) {
        // Partial update logic...
        return ResponseEntity.ok(patchedItem); // 200 OK
    }

    // 6. DELETE: Remove a resource
    @DeleteMapping("/items/{id}")
    public ResponseEntity<Void> deleteItem(@PathVariable int id) {
        itemDaoService.deleteById(id);
        return ResponseEntity.noContent().build(); // 204 No Content
    }
}

🚦 Different HTTP Error and Status Codes

Properly using HTTP Status Codes is vital for a clear contract between the server and the client. Spring’s ResponseEntity class makes it easy to return any status code.

Status CodeCategoryUse Case / MeaningSpring Boot Response
200SuccessOK. Standard response for successful HTTP requests (GET, PUT, DELETE).ResponseEntity.ok().body(...)
201SuccessCreated. Successful creation of a new resource (POST).ResponseEntity.created(uri).body(...)
204SuccessNo Content. Successful request, but no content to return (e.g., successful DELETE).ResponseEntity.noContent().build()
400Client ErrorBad Request. The server cannot process the request due to client error (e.g., malformed JSON).ResponseEntity.badRequest().body(...)
401Client ErrorUnauthorized. Authentication is required and has failed or not been provided.Handled by Spring Security.
403Client ErrorForbidden. The client is authenticated but does not have permission to access the resource.Handled by Spring Security.
404Client ErrorNot Found. The requested resource could not be found.Throw a custom ResponseStatusException or NotFoundException.
500Server ErrorInternal Server Error. A generic error occurred on the server.Thrown by default for unhandled exceptions.