Spring REST API
Building REST APIs with Spring
Spring makes it easy to build RESTful web services. The key annotations are @RestController (combines @Controller and @ResponseBody), @RequestBody for reading JSON input, and ResponseEntity for full control over the HTTP response.
package com.example.controller;
import com.example.entity.User;
import com.example.service.UserService;
import org.springframework.data.domain.*;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.net.URI;
@RestController
@RequestMapping("/api/v1/users")
@CrossOrigin(origins = "http://localhost:3000") // Allow CORS from React app
public class UserRestController {
private final UserService userService;
public UserRestController(UserService userService) {
this.userService = userService;
}
// GET /api/v1/users?page=0&size=10&sort=username
@GetMapping
public ResponseEntity<Page<User>> getUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "id") String sort) {
Page<User> users = userService.getUsers(page, size, sort);
return ResponseEntity.ok(users);
}
// GET /api/v1/users/42
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = userService.getUserById(id);
return ResponseEntity.ok(user);
}
// POST /api/v1/users
@PostMapping
public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
User created = userService.createUser(user);
URI location = URI.create("/api/v1/users/" + created.getId());
return ResponseEntity.created(location).body(created); // 201 Created
}
// PUT /api/v1/users/42
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id,
@Valid @RequestBody User user) {
User updated = userService.updateUser(id, user);
return ResponseEntity.ok(updated);
}
// DELETE /api/v1/users/42
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
return ResponseEntity.noContent().build(); // 204 No Content
}
}
Exception Handling
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import java.util.*;
@RestControllerAdvice // Handles exceptions for all @RestController classes
public class GlobalExceptionHandler {
// Handle resource not found
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException ex) {
ErrorResponse error = new ErrorResponse(404, ex.getMessage());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
// Handle validation errors
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidation(
MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach(error -> {
String field = ((FieldError) error).getField();
String message = error.getDefaultMessage();
errors.put(field, message);
});
return ResponseEntity.badRequest().body(errors);
}
// Handle all other exceptions
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGeneral(Exception ex) {
ErrorResponse error = new ErrorResponse(500, "Internal server error");
return ResponseEntity.internalServerError().body(error);
}
record ErrorResponse(int status, String message) {}
}
CORS Configuration
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:3000", "https://myapp.com")
.allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600); // Cache preflight for 1 hour
}
}
// Or use @CrossOrigin on individual controllers/methods:
// @CrossOrigin(origins = "*", maxAge = 3600)
// @CrossOrigin(origins = {"http://localhost:3000", "https://myapp.com"})
Ready to Level Up Your Skills?
Explore 500+ free tutorials across 20+ languages and frameworks.