Structure API Responses in
Spring Boot
A good API response should:
1. Be Predictable: Use a consistent format for both success and error
responses.
2. Be Informative: Include relevant data and metadata.
3. Be Descriptive: Clearly indicate the request status.
4. Be Simple: Avoid unnecessary complexity.
A common way to standardize API responses is by wrapping the data in a
response object.
This object can include:
Status: HTTP status codes (e.g., 200, 404).
Message: A short description of the outcome.
Data: The actual payload (can be null for error cases).
Metadata: Optional information like pagination details.
Here’s an example of a standard response structure in JSON format:
{
"status": "success",
"message": "Data retrieved successfully",
"data": {
"id": 1,
"name": "Youssef Alboghdady"
},
"metadata": {
"page": 1,
"size": 10,
"total": 100
Structure API Responses in Spring Boot 1
}
}
In Spring Boot, you can define a generic ApiResponse class to standardize
responses:
public class ApiResponse<T> {
private String status; // e.g., "success" or "error"
private String message; // Descriptive message about the response
private T data; // The actual data payload
private Object metadata; // Additional metadata (e.g., pagination info)
// Constructor
public ApiResponse(String status, String message, T data, Object metad
ata) {
[Link] = status;
[Link] = message;
[Link] = data;
[Link] = metadata;
}
// Getters_Setters
}
Key Features of the ApiResponse Class
1. Generic Type ( T ): Allows the response to handle any type of data payload.
2. Status: Indicates the outcome of the request (e.g., "success" , "error" ).
3. Message: Provides a descriptive message about the response.
4. Data: Contains the actual payload (e.g., a list of objects, a single object,
etc.).
5. Metadata: Optional field for additional information (e.g., pagination details,
timestamps).
Structure API Responses in Spring Boot 2
You can use the ApiResponse class to wrap successful responses. For example:
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public ResponseEntity<ApiResponse<User>> getUserById(@PathVariabl
e Long id) {
User user = [Link](id);
ApiResponse<User> response = new ApiResponse<>(
"success",
"User retrieved successfully",
user,
null
);
return [Link](response);
}
}
This ensures that every successful response follows a consistent format.
For error handling, you can extend the same ApiResponse class to include error-
specific details:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler([Link])
public ResponseEntity<ApiResponse<Object>> handleResourceNotFoun
d(ResourceNotFoundException ex) {
ApiResponse<Object> response = new ApiResponse<>(
"error",
[Link](),
null,
null
);
Structure API Responses in Spring Boot 3
return [Link](HttpStatus.NOT_FOUND).body(respons
e);
}
}
Using a Utility Class for Responses
To avoid repetitive code, you can create a utility class for generating
responses:
public class ResponseUtil {
public static <T> ApiResponse<T> success(String message, T data, Objec
t metadaa) {
return new ApiResponse<>("success", message, data, metadata);
}
public static <T> ApiResponse<T> error(String message, T data) {
return new ApiResponse<>("error", message, data, null);
}
And use it in your controllers:
@GetMapping("/{id}")
public ResponseEntity<ApiResponse<User>> getUserById(@PathVariable
Long id) {
User user = [Link](id);
return [Link]([Link]("User retrieved success
fully", user, null));
}
Structure API Responses in Spring Boot 4