❌ NAHI! ApiResponse Inbuilt NAHI Hai
ApiResponse Khud Banana Padta Hai 🛠️
// Ye aapko KHUD banana hota hai - Standard industry practice
package com.company.ecommerce.dto.response;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.*;
import java.util.List;
/**
* Standard API Response Wrapper
* Ye class aapko khud banani padegi
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL) // null fields skip karenge
public class ApiResponse<T> {
private Boolean success;
private String message;
private T data;
private List<String> errors;
private Long timestamp;
private String path;
// Helper static methods
public static <T> ApiResponse<T> success(T data) {
return ApiResponse.<T>builder()
.success(true)
.data(data)
.timestamp(System.currentTimeMillis())
.build();
}
public static <T> ApiResponse<T> success(String message, T data) {
return ApiResponse.<T>builder()
.success(true)
.message(message)
.data(data)
.timestamp(System.currentTimeMillis())
.build();
}
public static <T> ApiResponse<T> error(String message) {
return ApiResponse.<T>builder()
.success(false)
.message(message)
.timestamp(System.currentTimeMillis())
.build();
}
public static <T> ApiResponse<T> error(String message, List<String> errors) {
return ApiResponse.<T>builder()
.success(false)
.message(message)
.errors(errors)
.timestamp(System.currentTimeMillis())
.build();
}
}
Kyu Banana Padta Hai?
✅ Benefits:
1. CONSISTENCY
Sab endpoints same format mein response denge
2. ERROR HANDLING
Success/failure easily differentiate kar sakte
3. METADATA
Timestamp, pagination, etc add kar sakte
4. CLIENT EASY
Frontend developers ko parsing easy hogi
Response Format Examples
1. Success Response:
{
"success": true,
"message": "Product created successfully",
"data": {
"id": 123,
"name": "Laptop",
"price": 50000
},
"timestamp": 1709388000000
}
2. Error Response:
{
"success": false,
"message": "Validation failed",
"errors": [
"Name is required",
"Price must be greater than 0"
],
"timestamp": 1709388000000,
"path": "/api/products"
}
3. List Response:
{
"success": true,
"data": [
{"id": 1, "name": "Product 1"},
{"id": 2, "name": "Product 2"}
],
"timestamp": 1709388000000
}
Controller Mein Kaise Use Kare
@RestController
@RequestMapping("/api/products")
public class ProductController {
// Success case
@PostMapping
public ResponseEntity<ApiResponse<ProductResponse>> create(
@RequestBody ProductRequest request
) {
Product product = productService.create(request);
return ResponseEntity
.status(HttpStatus.CREATED)
.body(ApiResponse.success(
"Product created successfully",
productMapper.toResponse(product)
));
}
// List response
@GetMapping
public ResponseEntity<ApiResponse<List<ProductResponse>>> getAll() {
List<Product> products = productService.findAll();
return ResponseEntity.ok(
ApiResponse.success(productMapper.toResponseList(products))
);
}
// Error will be handled by GlobalExceptionHandler
}
Alternative: Spring Boot Inbuilt ResponseEntity
// Agar ApiResponse nahi banana chahte, to sirf ResponseEntity use kar sakte ho
@GetMapping("/{id}")
public ResponseEntity<ProductResponse> getProduct(@PathVariable Long id) {
Product product = productService.findById(id);
return ResponseEntity.ok(productMapper.toResponse(product));
}
// Response:
{
"id": 123,
"name": "Laptop",
"price": 50000
}
// But yahan consistency nahi hai
// Kabhi direct object, kabhi error format different
Industry Standard Wrapper Variations
Option 1: Simple Wrapper
@Data
@AllArgsConstructor
public class ApiResponse<T> {
private boolean success;
private T data;
private String message;
}
Option 2: Detailed Wrapper (Recommended)
@Data
@Builder
public class ApiResponse<T> {
private Boolean success;
private String message;
private T data;
private List<String> errors;
private Integer statusCode;
private Long timestamp;
private String path;
private String requestId; // For tracing
}
Option 3: Separate Success/Error Classes
// Success Response
@Data
@AllArgsConstructor
public class SuccessResponse<T> {
private T data;
private String message;
private Long timestamp;
}
// Error Response
@Data
@AllArgsConstructor
public class ErrorResponse {
private String message;
private List<String> errors;
private Integer statusCode;
private String path;
private Long timestamp;
}
Companies Mein Kaisa Use Hota Hai
Company 1: Flipkart Style
{
"status": "success",
"code": 200,
"data": { ... },
"meta": {
"timestamp": "2024-02-02T10:30:00Z",
"requestId": "abc-123-xyz"
}
}
Company 2: Amazon Style
{
"result": { ... },
"metadata": {
"statusCode": 200,
"message": "Success"
}
}
Company 3: Google Style
{
"data": { ... },
"error": null
}
Complete Example with GlobalExceptionHandler
// ApiResponse class
@Data
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiResponse<T> {
private Boolean success;
private String message;
private T data;
private List<String> errors;
private Long timestamp;
private String path;
public static <T> ApiResponse<T> success(T data) {
return ApiResponse.<T>builder()
.success(true)
.data(data)
.timestamp(System.currentTimeMillis())
.build();
}
public static <T> ApiResponse<T> error(String message, String path) {
return ApiResponse.<T>builder()
.success(false)
.message(message)
.timestamp(System.currentTimeMillis())
.path(path)
.build();
}
}
// GlobalExceptionHandler
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ApiResponse<Void> handleNotFound(
ResourceNotFoundException ex,
HttpServletRequest request
) {
return ApiResponse.error(ex.getMessage(), request.getRequestURI());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiResponse<Void> handleValidation(
MethodArgumentNotValidException ex,
HttpServletRequest request
) {
List<String> errors = ex.getBindingResult()
.getFieldErrors()
.stream()
.map(error -> error.getField() + ": " + error.getDefaultMessage())
.collect(Collectors.toList());
return ApiResponse.<Void>builder()
.success(false)
.message("Validation failed")
.errors(errors)
.timestamp(System.currentTimeMillis())
.path(request.getRequestURI())
.build();
}
}
Key Takeaways
✅ ApiResponse INBUILT NAHI HAI
✅ Khud banana padta hai (Industry standard)
✅ Consistency ke liye important
✅ Error handling easy hoti hai
✅ Frontend integration smooth hota hai
❌ Spring Boot mein koi default wrapper nahi
❌ ResponseEntity sirf HTTP control deta hai
Quick Template - Copy Paste Karo
package com.yourcompany.dto.response;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.*;
import java.util.List;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiResponse<T> {
private Boolean success;
private String message;
private T data;
private List<String> errors;
private Long timestamp;
public static <T> ApiResponse<T> success(T data) {
return ApiResponse.<T>builder()
.success(true)
.data(data)
.timestamp(System.currentTimeMillis())
.build();
}
public static <T> ApiResponse<T> success(String message, T data) {
return ApiResponse.<T>builder()
.success(true)
.message(message)
.data(data)
.timestamp(System.currentTimeMillis())
.build();
}
public static <T> ApiResponse<T> error(String message) {
return ApiResponse.<T>builder()
.success(false)
.message(message)
.timestamp(System.currentTimeMillis())
.build();
}
public static <T> ApiResponse<T> error(String message, List<String> errors) {
return ApiResponse.<T>builder()
.success(false)
.message(message)
.errors(errors)
.timestamp(System.currentTimeMillis())
.build();
}
}
Yeh file apne project mein add karo aur use karo! 🚀
Top comments (0)