Module 3 - Creating RESTful Web Services
Conceptual Overview
What is REST?
REST (Representational State Transfer) is an architectural style for designing networked applications. The key principles that define a RESTful system include:
- Client-Server Architecture: Separation of concerns between the client (user interface) and server (data storage)
- Statelessness: Each request contains all the information needed to complete it
- Cacheability: Responses must define themselves as cacheable or non-cacheable
- Uniform Interface: Resources are identified by URIs, and interactions happen through standard HTTP methods
- Layered System: A client cannot tell whether it’s connected directly to the end server or to an intermediary
- Code on Demand (optional): Servers can temporarily extend client functionality by transferring executable code
HTTP Methods in RESTful APIs
REST APIs leverage HTTP methods to perform operations on resources:
HTTP Method | Purpose | Idempotent? | Safe? |
---|---|---|---|
GET | Retrieve resource(s) | Yes | Yes |
POST | Create a new resource | No | No |
PUT | Update a resource (complete replacement) | Yes | No |
PATCH | Partial update of a resource | Yes | No |
DELETE | Remove a resource | Yes | No |
Idempotent: Multiple identical requests have the same effect as a single request Safe: Operation doesn’t alter the state of the server
RESTful Resource Naming
Good practices for resource naming include:
- Use nouns, not verbs (
/books
not/getBooks
) - Use plural nouns for collections (
/books
instead of/book
) - Use hierarchical relationships (
/authors/123/books
) - Use hyphens for word separation (
/book-reviews
not/book_reviews
or/bookReviews
)
Spring Boot REST Fundamentals
Spring Boot provides excellent support for building RESTful APIs through:
@RestController
: Combines@Controller
and@ResponseBody
annotations, indicating that method returns are directly written to the response body, not resolved as view names@RequestMapping
: Specifies the base URL path for controller methods@GetMapping
,@PostMapping
, etc.: Shortcuts for HTTP method-specific mappings@PathVariable
: Extracts values from the URI path@RequestParam
: Extracts values from query parameters@RequestBody
: Binds request body to a method parameterResponseEntity
: Provides complete control over the HTTP response, including status codes and headers
HTTP Status Codes
Proper status code selection is crucial for RESTful services:
-
2xx Success
- 200 OK: Standard success
- 201 Created: Resource successfully created
- 204 No Content: Success but no response body
-
4xx Client Error
- 400 Bad Request: Malformed request syntax
- 401 Unauthorized: Authentication required
- 403 Forbidden: Valid credentials but insufficient permissions
- 404 Not Found: Resource doesn’t exist
- 405 Method Not Allowed: Valid resource but HTTP method not supported
-
5xx Server Error
- 500 Internal Server Error: Generic server error
- 502 Bad Gateway: Invalid response from upstream server
- 503 Service Unavailable: Server temporarily unavailable
API Documentation with Spring Boot
Spring Boot integrates with OpenAPI (formerly Swagger) for API documentation:
- SpringDoc library automates the generation of API documentation
- Swagger UI provides an interactive interface to explore and test the API
- OpenAPI Specification produces a machine-readable description of your API
Monitoring with Spring Boot Actuator
Spring Boot Actuator provides production-ready features to monitor and manage applications:
- Endpoints: Pre-defined endpoints exposing operational information
- Health checks: Indicators of application health
- Metrics: Application performance and resource consumption data
- Auditing: Tracking security-related events
Lecture: Creating RESTful APIs with Spring Boot
Introduction to REST Controllers
In Spring Boot, REST controllers are defined using the @RestController
annotation:
@RestController
@RequestMapping("/api/books")
public class BookController {
// Controller methods go here
}
Unlike traditional MVC controllers, REST controllers automatically serialize returned objects to JSON (or XML), eliminating the need for a separate view layer.
Handling Different HTTP Methods
Each HTTP method corresponds to a specific operation on resources:
// GET /api/books
@GetMapping
public List<Book> getAllBooks() {
return bookService.findAll();
}
// GET /api/books/123
@GetMapping("/{id}")
public Book getBookById(@PathVariable Long id) {
return bookService.findById(id);
}
// POST /api/books
@PostMapping
public ResponseEntity<Book> createBook(@RequestBody Book book) {
Book savedBook = bookService.save(book);
return ResponseEntity.status(HttpStatus.CREATED).body(savedBook);
}
// PUT /api/books/123
@PutMapping("/{id}")
public ResponseEntity<Book> updateBook(@PathVariable Long id, @RequestBody Book book) {
Book updatedBook = bookService.update(id, book);
return ResponseEntity.ok(updatedBook);
}
// DELETE /api/books/123
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteBook(@PathVariable Long id) {
bookService.delete(id);
return ResponseEntity.noContent().build();
}
Request Validation
Spring Boot integrates with Bean Validation (JSR-380) to validate incoming requests:
@PostMapping
public ResponseEntity<Book> createBook(@Valid @RequestBody Book book) {
Book savedBook = bookService.save(book);
return ResponseEntity.status(HttpStatus.CREATED).body(savedBook);
}
The @Valid
annotation triggers validation of the request body. Validation constraints are defined in the model class:
public class Book {
@NotBlank(message = "Title cannot be blank")
private String title;
@NotBlank(message = "Author cannot be blank")
private String author;
@Min(value = 1, message = "Page count must be greater than 0")
private int pageCount;
// getters and setters
}
Error Handling
In RESTful applications, error handling should be consistent and follow API conventions:
@RestControllerAdvice
public class RestExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleResourceNotFound(ResourceNotFoundException ex) {
ErrorResponse error = new ErrorResponse(
HttpStatus.NOT_FOUND.value(),
ex.getMessage(),
System.currentTimeMillis()
);
return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidationExceptions(MethodArgumentNotValidException ex) {
List<String> errors = ex.getBindingResult()
.getAllErrors()
.stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.toList());
ErrorResponse error = new ErrorResponse(
HttpStatus.BAD_REQUEST.value(),
"Validation failed",
System.currentTimeMillis(),
errors
);
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
}
Testing REST Controllers
Spring Boot provides excellent support for testing REST controllers:
@SpringBootTest
@AutoConfigureMockMvc
public class BookControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private BookService bookService;
@Test
public void testGetAllBooks() throws Exception {
List<Book> books = Arrays.asList(
new Book(1L, "Clean Code", "Robert Martin", 464),
new Book(2L, "Effective Java", "Joshua Bloch", 416)
);
when(bookService.findAll()).thenReturn(books);
mockMvc.perform(get("/api/books"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(2)))
.andExpect(jsonPath("$[0].title", is("Clean Code")))
.andExpect(jsonPath("$[1].title", is("Effective Java")));
}
}
Spring Boot Actuator
Spring Boot Actuator adds production-ready features to your application:
# Add to application.properties
management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=always
With these settings, you can access:
/actuator/health
: Application health information/actuator/info
: Application information/actuator/metrics
: Application metrics
API Documentation with SpringDoc
To add OpenAPI documentation:
- Add the SpringDoc dependency:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.7.0</version>
</dependency>
- Configure the OpenAPI info:
@Configuration
public class OpenApiConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("Book Catalog API")
.version("1.0")
.description("A simple Book Catalog API"));
}
}
- Enhance controllers and models with OpenAPI annotations:
@Operation(summary = "Get all books", description = "Returns a list of all books in the catalog")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successfully retrieved books")
})
@GetMapping
public List<Book> getAllBooks() {
return bookService.findAll();
}
With this configuration, you can access the Swagger UI at /swagger-ui.html
.
Quiz: RESTful Web Services
-
What does REST stand for? a) Representational State Transfer b) Remote Service Technology c) Responsive System Transfer d) Remote State Transfer
-
Which HTTP method should be used to retrieve a resource without modifying it? a) POST b) GET c) PUT d) DELETE
-
Which HTTP status code is most appropriate for a successful resource creation? a) 200 OK b) 201 Created c) 202 Accepted d) 204 No Content
-
In Spring Boot, which annotation combines
@Controller
and@ResponseBody
? a) @ApiController b) @WebController c) @RestController d) @HttpController -
Which annotation is used to extract values from the URI path in Spring Boot? a) @PathVariable b) @PathParam c) @UriParam d) @RequestPath
-
Which is NOT a characteristic of a RESTful service? a) Statelessness b) Uniform interface c) Client-server architecture d) Session management
-
To validate a request body in Spring Boot, which annotation is used? a) @Validate b) @Valid c) @RequestValidation d) @Validated
-
Which Spring Boot starter is used to add monitoring and management capabilities? a) spring-boot-starter-monitor b) spring-boot-starter-management c) spring-boot-starter-actuator d) spring-boot-starter-admin
-
Which HTTP method is idempotent? a) GET b) POST c) Both a and b d) Neither a nor b
-
In a RESTful API, what is the recommended way to name resources? a) Use verbs like /getBooks b) Use singular nouns like /book c) Use plural nouns like /books d) Use camelCase like /getBookByAuthor
Quiz Answers
-
What does REST stand for? Answer: a) Representational State Transfer
-
Which HTTP method should be used to retrieve a resource without modifying it? Answer: b) GET
-
Which HTTP status code is most appropriate for a successful resource creation? Answer: b) 201 Created
-
In Spring Boot, which annotation combines
@Controller
and@ResponseBody
? Answer: c) @RestController -
Which annotation is used to extract values from the URI path in Spring Boot? Answer: a) @PathVariable
-
Which is NOT a characteristic of a RESTful service? Answer: d) Session management
-
To validate a request body in Spring Boot, which annotation is used? Answer: b) @Valid
-
Which Spring Boot starter is used to add monitoring and management capabilities? Answer: c) spring-boot-starter-actuator
-
Which HTTP method is idempotent? Answer: a) GET
-
In a RESTful API, what is the recommended way to name resources? Answer: c) Use plural nouns like /books
By Wahid Hamdi