Rest Controller
👉 Spring boot tutorial to Develop and Expose API over HTTP using Controllers / Rest Controllers.
RESTFul Service 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 and test with embedded server.
Table of Contents
- RESTFul Service Development
- Table of Contents
- Maven Dependency
- Creating REST Controllers
- Other HTTP Verbs
- HTTP Status Codes
Maven Dependency
The core functionality for creating REST services and handling the response entity is provided by the spring-boot-starter-web.
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Creating REST Controllers
In a Spring Boot application, the primary way to create controller this is by annoating the class with @Controller annotation.
Specifically, the @RestController annotation is a convenient shorthand, which combines the @Controller and @ResponseBody annotations.
On Application Booting Spring scans this class and finds that,
- This class handles incoming web requests - @RestController.
- The return value of the methods should be automatically converted to the response body (typically JSON or XML) - @ResponseBody.
Controller
We will utilize ServletUriComponentsBuilder to easily construct the newly created 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:
Check the project POC on Github - Social Media App.
HTTP POST Verb
When a resource is successfully created via a POST request, the response is returned with standard HTTP status code 201 Created. Best practice dictates including a Location header in the response, pointing to the newly created resource’s URI.
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.
Other HTTP Verbs
RESTful API relies entirely on the semantics of HTTP verbs (methods) to define the intended action on a resource.
Spring Boot abstracts this perfectly by providing specific, intention-revealing annotations for HTTP Verbs.
This approach ensures the API is self-describing and adheres to the uniform interface constraint of REST. The client knows exactly what behavior to expect just by looking at the verb and the URI structure.
REST Controller
// 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
}
}
HTTP Status Codes
Returning correct HTTP Status Codes is vital for a clear contract between the server and the client.
Spring’sResponseEntity class makes it easy for developers to control the status code returned in the response.
| Code | Category | Use Case / Meaning | Spring Boot Response |
|---|---|---|---|
200 | Success | OK. Standard response for successful HTTP requests (GET, PUT, DELETE). | ResponseEntity.ok().body(...) |
201 | Success | Created. Successful creation of a new resource (POST). | ResponseEntity.created(uri).body(...) |
204 | Success | No Content. Successful request, but no content to return (e.g., successful DELETE). | ResponseEntity.noContent().build() |
400 | Client Error | Bad Request. The server cannot process the request due to client error (e.g., malformed JSON). | ResponseEntity.badRequest().body(...) |
401 | Client Error | Unauthorized. Authentication is required and has failed or not been provided. | Handled by Spring Security. |
403 | Client Error | Forbidden. The client is authenticated but does not have permission to access the resource. | Handled by Spring Security. |
404 | Client Error | Not Found. The requested resource could not be found. | Throw a custom ResponseStatusException or NotFoundException. |
500 | Server Error | Internal Server Error. A generic error occurred on the server. | Thrown by default for unhandled exceptions. |