ResponseEntity - Complete Methods & Features List
π Status Code Methods
β Success Responses (2xx)
ResponseEntity.ok() // 200 OK
ResponseEntity.ok(body) // 200 OK with body
ResponseEntity.ok().build() // 200 OK without body
ResponseEntity.status(HttpStatus.OK).body(data) // 200 explicit
ResponseEntity.created(location) // 201 CREATED
ResponseEntity.created(location).body(data) // 201 with body
ResponseEntity.status(HttpStatus.CREATED).body(data)
ResponseEntity.accepted() // 202 ACCEPTED
ResponseEntity.accepted().body(data) // 202 with body
ResponseEntity.noContent() // 204 NO CONTENT
ResponseEntity.noContent().build() // 204 (common for DELETE)
β Client Error Responses (4xx)
ResponseEntity.badRequest() // 400 BAD REQUEST
ResponseEntity.badRequest().body(error) // 400 with error
ResponseEntity.status(HttpStatus.UNAUTHORIZED) // 401 UNAUTHORIZED
ResponseEntity.status(401).body(error) // 401 with message
ResponseEntity.status(HttpStatus.FORBIDDEN) // 403 FORBIDDEN
ResponseEntity.status(403).body(error) // 403 with message
ResponseEntity.notFound() // 404 NOT FOUND
ResponseEntity.notFound().build() // 404 (most common)
ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED) // 405
ResponseEntity.status(HttpStatus.CONFLICT) // 409 CONFLICT
ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY) // 422
ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS) // 429
π΄ Server Error Responses (5xx)
ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) // 500
ResponseEntity.status(500).body(error) // 500 with error
ResponseEntity.status(HttpStatus.BAD_GATEWAY) // 502
ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE) // 503
ResponseEntity.status(HttpStatus.GATEWAY_TIMEOUT) // 504
π Redirection Responses (3xx)
ResponseEntity.status(HttpStatus.MOVED_PERMANENTLY) // 301
.location(newUri).build()
ResponseEntity.status(HttpStatus.FOUND) // 302
.location(uri).build()
ResponseEntity.status(HttpStatus.NOT_MODIFIED) // 304
π― Builder Methods
Basic Building
ResponseEntity.status(statusCode) // Set status code
ResponseEntity.status(HttpStatus.OK) // Using enum
.body(data) // Set response body
.build() // Build without body
Headers
.header(name, value) // Single header
.headers(HttpHeaders) // Multiple headers
.contentType(MediaType) // Content-Type header
.location(URI) // Location header
.allow(HttpMethod...) // Allowed methods
Caching
.cacheControl(CacheControl) // Cache control
.cacheControl(CacheControl.maxAge(60, TimeUnit.SECONDS))
.cacheControl(CacheControl.noCache())
.cacheControl(CacheControl.noStore())
.eTag(String) // ETag header
.eTag("version-123")
.lastModified(long) // Last-Modified
.lastModified(ZonedDateTime)
.lastModified(Instant)
Content
.contentLength(long) // Content-Length
.accept(MediaType...) // Accept header
.acceptCharset(Charset...) // Accept-Charset
.varyBy(String...) // Vary header
π¦ Generic Types
ResponseEntity<String> // String response
ResponseEntity<User> // Single object
ResponseEntity<List<User>> // List
ResponseEntity<Page<User>> // Paginated
ResponseEntity<Map<String, Object>> // Map
ResponseEntity<ApiResponse<User>> // Wrapper
ResponseEntity<byte[]> // Binary data
ResponseEntity<Resource> // File/Resource
ResponseEntity<Void> // No body
ResponseEntity<?> // Wildcard
π§ Content-Type Options
.contentType(MediaType.APPLICATION_JSON) // JSON
.contentType(MediaType.APPLICATION_XML) // XML
.contentType(MediaType.TEXT_PLAIN) // Plain text
.contentType(MediaType.TEXT_HTML) // HTML
.contentType(MediaType.APPLICATION_PDF) // PDF
.contentType(MediaType.IMAGE_PNG) // PNG image
.contentType(MediaType.IMAGE_JPEG) // JPEG image
.contentType(MediaType.APPLICATION_OCTET_STREAM) // Binary
.contentType(MediaType.MULTIPART_FORM_DATA) // Form data
.contentType(MediaType.parseMediaType("text/csv")) // CSV
.contentType(MediaType.parseMediaType(
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
)) // Excel
π₯ File Download Headers
// Download as attachment
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"file.pdf\"")
// Display inline (PDF in browser)
.header(HttpHeaders.CONTENT_DISPOSITION,
"inline; filename=\"document.pdf\"")
// Content length
.header(HttpHeaders.CONTENT_LENGTH, "12345")
// Complete file download
ResponseEntity.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"report.pdf\"")
.body(fileBytes)
π CORS Headers
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Origin", "https://example.com")
.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
.header("Access-Control-Allow-Headers", "Content-Type, Authorization")
.header("Access-Control-Allow-Credentials", "true")
.header("Access-Control-Max-Age", "3600")
π Security Headers
.header("X-Content-Type-Options", "nosniff")
.header("X-Frame-Options", "DENY")
.header("X-XSS-Protection", "1; mode=block")
.header("Strict-Transport-Security", "max-age=31536000")
.header("Content-Security-Policy", "default-src 'self'")
π¨ Custom Headers
.header("X-Request-Id", UUID.randomUUID().toString())
.header("X-User-Id", "123")
.header("X-API-Version", "v1")
.header("X-Rate-Limit-Remaining", "99")
.header("X-Total-Count", "1000")
.header("X-Page-Number", "1")
π All HTTP Status Codes (HttpStatus Enum)
1xx Informational
HttpStatus.CONTINUE // 100
HttpStatus.SWITCHING_PROTOCOLS // 101
HttpStatus.PROCESSING // 102
2xx Success
HttpStatus.OK // 200 β
HttpStatus.CREATED // 201 β
HttpStatus.ACCEPTED // 202 β
HttpStatus.NON_AUTHORITATIVE_INFORMATION // 203
HttpStatus.NO_CONTENT // 204 β
HttpStatus.RESET_CONTENT // 205
HttpStatus.PARTIAL_CONTENT // 206
HttpStatus.MULTI_STATUS // 207
3xx Redirection
HttpStatus.MULTIPLE_CHOICES // 300
HttpStatus.MOVED_PERMANENTLY // 301 β
HttpStatus.FOUND // 302 β
HttpStatus.SEE_OTHER // 303
HttpStatus.NOT_MODIFIED // 304 β
HttpStatus.TEMPORARY_REDIRECT // 307
HttpStatus.PERMANENT_REDIRECT // 308
4xx Client Errors
HttpStatus.BAD_REQUEST // 400 β
HttpStatus.UNAUTHORIZED // 401 β
HttpStatus.PAYMENT_REQUIRED // 402
HttpStatus.FORBIDDEN // 403 β
HttpStatus.NOT_FOUND // 404 β
HttpStatus.METHOD_NOT_ALLOWED // 405 β
HttpStatus.NOT_ACCEPTABLE // 406
HttpStatus.PROXY_AUTHENTICATION_REQUIRED // 407
HttpStatus.REQUEST_TIMEOUT // 408
HttpStatus.CONFLICT // 409 β
HttpStatus.GONE // 410
HttpStatus.LENGTH_REQUIRED // 411
HttpStatus.PRECONDITION_FAILED // 412
HttpStatus.PAYLOAD_TOO_LARGE // 413
HttpStatus.URI_TOO_LONG // 414
HttpStatus.UNSUPPORTED_MEDIA_TYPE // 415
HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE // 416
HttpStatus.EXPECTATION_FAILED // 417
HttpStatus.I_AM_A_TEAPOT // 418 (joke)
HttpStatus.UNPROCESSABLE_ENTITY // 422 β
HttpStatus.LOCKED // 423
HttpStatus.FAILED_DEPENDENCY // 424
HttpStatus.TOO_EARLY // 425
HttpStatus.UPGRADE_REQUIRED // 426
HttpStatus.PRECONDITION_REQUIRED // 428
HttpStatus.TOO_MANY_REQUESTS // 429 β
HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE // 431
HttpStatus.UNAVAILABLE_FOR_LEGAL_REASONS // 451
5xx Server Errors
HttpStatus.INTERNAL_SERVER_ERROR // 500 β
HttpStatus.NOT_IMPLEMENTED // 501
HttpStatus.BAD_GATEWAY // 502 β
HttpStatus.SERVICE_UNAVAILABLE // 503 β
HttpStatus.GATEWAY_TIMEOUT // 504 β
HttpStatus.HTTP_VERSION_NOT_SUPPORTED // 505
HttpStatus.VARIANT_ALSO_NEGOTIATES // 506
HttpStatus.INSUFFICIENT_STORAGE // 507
HttpStatus.LOOP_DETECTED // 508
HttpStatus.BANDWIDTH_LIMIT_EXCEEDED // 509
HttpStatus.NOT_EXTENDED // 510
HttpStatus.NETWORK_AUTHENTICATION_REQUIRED // 511
π― Common Patterns
Pattern 1: Simple Success
ResponseEntity.ok(data)
Pattern 2: Created with Location
ResponseEntity.created(location).body(data)
Pattern 3: No Content (Delete)
ResponseEntity.noContent().build()
Pattern 4: Not Found
ResponseEntity.notFound().build()
Pattern 5: Bad Request with Error
ResponseEntity.badRequest().body(errorMessage)
Pattern 6: Conditional Response
data != null
? ResponseEntity.ok(data)
: ResponseEntity.notFound().build()
Pattern 7: With Custom Headers
ResponseEntity.ok()
.header("X-Custom", "value")
.contentType(MediaType.APPLICATION_JSON)
.body(data)
Pattern 8: File Download
ResponseEntity.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"file.pdf\"")
.body(fileBytes)
Pattern 9: Cached Response
ResponseEntity.ok()
.cacheControl(CacheControl.maxAge(60, TimeUnit.SECONDS))
.eTag("version-1")
.body(data)
Pattern 10: Complex Builder
ResponseEntity
.status(HttpStatus.CREATED)
.contentType(MediaType.APPLICATION_JSON)
.header("X-Request-Id", requestId)
.cacheControl(CacheControl.noCache())
.location(uri)
.body(data)
β Most Used (90% Cases)
// Success
ResponseEntity.ok(data) // GET, PUT
ResponseEntity.created(location).body(data) // POST
ResponseEntity.noContent().build() // DELETE
// Errors
ResponseEntity.notFound().build() // 404
ResponseEntity.badRequest().body(error) // 400
ResponseEntity.status(500).body(error) // 500
// With headers
.header("name", "value")
.contentType(MediaType.APPLICATION_JSON)
π Quick Reference Table
| Use Case | Code | Status |
|---|---|---|
| Success (GET) | ResponseEntity.ok(data) |
200 |
| Created (POST) | ResponseEntity.created(uri).body(data) |
201 |
| Success (DELETE) | ResponseEntity.noContent().build() |
204 |
| Not Found | ResponseEntity.notFound().build() |
404 |
| Bad Input | ResponseEntity.badRequest().body(error) |
400 |
| Unauthorized | ResponseEntity.status(401).body(error) |
401 |
| Forbidden | ResponseEntity.status(403).body(error) |
403 |
| Server Error | ResponseEntity.status(500).body(error) |
500 |
| File Download | ResponseEntity.ok().contentType(...).body(bytes) |
200 |
| Conditional | data != null ? ok(data) : notFound().build() |
200/404 |
π Key Points
β
ResponseEntity is inbuilt (org.springframework.http)
β
Gives complete control over HTTP response
β
Can set status code, headers, body
β
Type-safe with generics
β
Builder pattern for fluent API
β
Immutable - thread-safe
β Not required for simple cases (Spring auto-converts)
β Don't use for every endpoint (only when control needed)
==================================
======================================
ResponseEntity - Internal Structure/Hierarchy
Class Hierarchy
java.lang.Object
β
org.springframework.http.HttpEntity<T>
β
org.springframework.http.ResponseEntity<T>
ResponseEntity Class Structure
public class ResponseEntity<T> extends HttpEntity<T> {
// Fields (inherited + own)
private final HttpStatusCode status; // Status code (200, 404, etc.)
// From HttpEntity: body (T), headers (HttpHeaders)
// Constructors
public ResponseEntity(HttpStatusCode status) { }
public ResponseEntity(T body, HttpStatusCode status) { }
public ResponseEntity(MultiValueMap<String, String> headers,
HttpStatusCode status) { }
public ResponseEntity(T body,
MultiValueMap<String, String> headers,
HttpStatusCode status) { }
// Static Factory Methods (Builder Pattern)
public static BodyBuilder status(HttpStatusCode status) { }
public static BodyBuilder ok() { }
public static <T> ResponseEntity<T> ok(T body) { }
public static BodyBuilder created(URI location) { }
public static BodyBuilder accepted() { }
public static BodyBuilder noContent() { }
public static BodyBuilder badRequest() { }
public static HeadersBuilder<?> notFound() { }
// Getters
public HttpStatusCode getStatusCode() { }
public int getStatusCodeValue() { } // Deprecated in newer versions
// From HttpEntity
public T getBody() { }
public HttpHeaders getHeaders() { }
public boolean hasBody() { }
}
ResponseEntity ke 3 Main Parts
βββββββββββββββββββββββββββββββββββ
β ResponseEntity<T> β
βββββββββββββββββββββββββββββββββββ€
β β
β 1. Status Code (HttpStatus) β
β ββββ 200 (OK) β
β ββββ 201 (CREATED) β
β ββββ 404 (NOT_FOUND) β
β ββββ 500 (ERROR) β
β β
β 2. Headers (HttpHeaders) β
β ββββ Content-Type β
β ββββ Authorization β
β ββββ Custom headers β
β β
β 3. Body (Generic Type T) β
β ββββ User object β
β ββββ List<User> β
β ββββ String β
β ββββ Any POJO β
β β
βββββββββββββββββββββββββββββββββββ
Builder Pattern - Nested Classes
// ResponseEntity ke andar nested interfaces/classes
public interface BodyBuilder extends HeadersBuilder<BodyBuilder> {
BodyBuilder contentLength(long contentLength);
BodyBuilder contentType(MediaType contentType);
<T> ResponseEntity<T> body(T body);
}
public interface HeadersBuilder<B extends HeadersBuilder<B>> {
B header(String headerName, String... headerValues);
B headers(HttpHeaders headers);
ResponseEntity<Void> build();
}
Practical Example - Internal Flow
@GetMapping("/user/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
// Step 1: ResponseEntity.ok() β Creates BodyBuilder
// Step 2: body(user) β Sets body and returns ResponseEntity
User user = new User(id, "Raj", "raj@email.com");
return ResponseEntity
.ok() // status = 200
.header("X-Custom", "MyValue") // headers set
.body(user); // body set, ResponseEntity created
}
Memory Structure
ResponseEntity Instance:
{
status: HttpStatus.OK (200),
headers: {
"Content-Type": "application/json",
"X-Custom": "MyValue"
},
body: User {
id: 1,
name: "Raj",
email: "raj@email.com"
}
}
Key Points
-
Generic Class hai:
ResponseEntity<T>- T koi bhi type ho sakta hai - Immutable hai: Ek baar create karne ke baad change nahi hota
- Builder Pattern use karta hai: Fluent API ke liye
- HttpEntity ko extend karta hai: Body aur headers inherit karta hai
- HttpStatus enum use karta hai: Predefined status codes ke liye
Yeh structure Spring Framework mein predefined hai, aapko sirf use karna hai! π―
==========================================================
============================================================
Spring Boot Controller - Complete Learning Pattern
π― Step-by-Step Learning Roadmap
LEVEL 1: Basic Annotations Samjho
1. Controller Banane ke Annotations
@RestController // JSON/XML response deta hai (REST API ke liye)
@Controller // View/HTML return karta hai (traditional web apps)
@RequestMapping("/api") // Base URL for entire controller
2. HTTP Methods ke Annotations
@GetMapping // Data READ karne ke liye
@PostMapping // Data CREATE karne ke liye
@PutMapping // Data UPDATE karne ke liye (complete)
@PatchMapping // Data UPDATE karne ke liye (partial)
@DeleteMapping // Data DELETE karne ke liye
LEVEL 2: Request Data Kaise Receive Kare
Pattern: 5 Tarike se data aata hai
@RestController
@RequestMapping("/api/users")
public class UserController {
// 1. PATH VARIABLE - URL mein data
@GetMapping("/{id}") // /api/users/123
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
// 2. REQUEST PARAM - Query string mein data
@GetMapping // /api/users?name=Raj&age=25
public List<User> searchUsers(
@RequestParam String name,
@RequestParam(required = false) Integer age
) {
return userService.search(name, age);
}
// 3. REQUEST BODY - JSON/XML body mein data
@PostMapping
public User createUser(@RequestBody User user) {
return userService.save(user);
}
// 4. REQUEST HEADER - Headers mein data
@GetMapping("/secure")
public String secureData(
@RequestHeader("Authorization") String token
) {
return "Token: " + token;
}
// 5. MODEL ATTRIBUTE - Form data ke liye
@PostMapping("/form")
public String submitForm(@ModelAttribute User user) {
userService.save(user);
return "success";
}
}
LEVEL 3: Response Kaise Bheje
Pattern: 3 Ways to Return Data
@RestController
@RequestMapping("/api/products")
public class ProductController {
// WAY 1: Direct Object Return (Simple)
@GetMapping("/{id}")
public Product getProduct(@PathVariable Long id) {
return productService.findById(id); // Auto 200 OK
}
// WAY 2: ResponseEntity (Control chahiye)
@GetMapping("/detail/{id}")
public ResponseEntity<Product> getProductDetail(@PathVariable Long id) {
Product product = productService.findById(id);
if (product != null) {
return ResponseEntity.ok(product); // 200
} else {
return ResponseEntity.notFound().build(); // 404
}
}
// WAY 3: ResponseEntity with Custom Response
@PostMapping
public ResponseEntity<ApiResponse> createProduct(@RequestBody Product product) {
Product saved = productService.save(product);
ApiResponse response = new ApiResponse(
"Product created successfully",
saved,
HttpStatus.CREATED.value()
);
return ResponseEntity
.status(HttpStatus.CREATED)
.header("X-Product-Id", saved.getId().toString())
.body(response);
}
}
LEVEL 4: CRUD Pattern - Sabse Important
Standard CRUD Controller Template
@RestController
@RequestMapping("/api/books")
public class BookController {
@Autowired
private BookService bookService;
// CREATE - POST
@PostMapping
public ResponseEntity<Book> createBook(@RequestBody Book book) {
Book saved = bookService.save(book);
return ResponseEntity.status(HttpStatus.CREATED).body(saved);
}
// READ ALL - GET
@GetMapping
public ResponseEntity<List<Book>> getAllBooks() {
List<Book> books = bookService.findAll();
return ResponseEntity.ok(books);
}
// READ ONE - GET with ID
@GetMapping("/{id}")
public ResponseEntity<Book> getBook(@PathVariable Long id) {
Book book = bookService.findById(id);
if (book != null) {
return ResponseEntity.ok(book);
}
return ResponseEntity.notFound().build();
}
// UPDATE - PUT
@PutMapping("/{id}")
public ResponseEntity<Book> updateBook(
@PathVariable Long id,
@RequestBody Book book
) {
Book updated = bookService.update(id, book);
if (updated != null) {
return ResponseEntity.ok(updated);
}
return ResponseEntity.notFound().build();
}
// DELETE - DELETE
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteBook(@PathVariable Long id) {
boolean deleted = bookService.delete(id);
if (deleted) {
return ResponseEntity.noContent().build(); // 204
}
return ResponseEntity.notFound().build(); // 404
}
}
LEVEL 5: Validation Add Karo
@RestController
@RequestMapping("/api/employees")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@PostMapping
public ResponseEntity<Employee> createEmployee(
@Valid @RequestBody Employee employee // @Valid for validation
) {
Employee saved = employeeService.save(employee);
return ResponseEntity.status(HttpStatus.CREATED).body(saved);
}
}
// Employee class mein validation
public class Employee {
@NotNull(message = "Name is required")
@Size(min = 2, max = 50)
private String name;
@Email(message = "Invalid email format")
private String email;
@Min(value = 18, message = "Age must be at least 18")
private Integer age;
// getters, setters
}
LEVEL 6: Exception Handling
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping("/{id}")
public ResponseEntity<Order> getOrder(@PathVariable Long id) {
try {
Order order = orderService.findById(id);
return ResponseEntity.ok(order);
} catch (OrderNotFoundException e) {
return ResponseEntity.notFound().build();
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
}
// Global Exception Handler (Better approach)
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(OrderNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(OrderNotFoundException ex) {
ErrorResponse error = new ErrorResponse(
HttpStatus.NOT_FOUND.value(),
ex.getMessage(),
LocalDateTime.now()
);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
}
π Learning Pattern - Yaad Rakhne ke Tips
1. URL Pattern
HTTP_METHOD /base-path/resource/{id}?queryParam=value
2. Controller Flow
Request β Controller β Service β Repository β Database
β
Response β Controller β Service β Repository β Database
3. Common Status Codes
- 200 OK - Success (GET, PUT)
- 201 Created - Resource created (POST)
- 204 No Content - Success but no data (DELETE)
- 400 Bad Request - Validation error
- 404 Not Found - Resource not found
- 500 Internal Server Error - Server error
4. Practice Template
@RestController
@RequestMapping("/api/{resource-name}")
public class {Resource}Controller {
@Autowired
private {Resource}Service service;
@PostMapping // CREATE
@GetMapping // READ ALL
@GetMapping("/{id}") // READ ONE
@PutMapping("/{id}") // UPDATE
@DeleteMapping("/{id}") // DELETE
}
π Practice Kaise Kare
- Simple CRUD bano - Student, Product, Book
- Postman se test karo - Har endpoint test karo
- Validation add karo - Input validation
- Exception handling add karo - Error scenarios
- Custom responses bano - ResponseEntity use karo
Yeh pattern follow karo, 2-3 projects bana lo, sab clear ho jayega! πͺ
================================
============================================
===========================================================
Controller Code Kaise Likhe - Step by Step Thinking Process π§
π― STEP 1: Requirements Samjho - Kya Banana Hai?
Example: E-commerce Order System
Requirements:
- User order create kar sake
- User apne orders dekh sake
- Admin sab orders dekh sake
- Order cancel kar sake
π₯ STEP 2: Sochne Ka Pattern - Mental Checklist
Har Feature Ke Liye 6 Sawaal Pucho:
1. KYA karna hai? (What)
β Order create karna hai
2. KON karega? (Who)
β User karega (authentication chahiye)
3. KAHAN se data aayega? (Input)
β Request body se JSON aayega
4. KYA validation chahiye? (Validation)
β Items empty nahi hone chahiye
β Price valid hona chahiye
5. KAHAN bhejenge? (Process)
β Service layer ko bhejenge business logic ke liye
6. KYA return karenge? (Output)
β Created order ka data with status 201
π STEP 3: Real Example - Order Controller Banana
Mental Process Dikhata Hoon:
Requirement: "User order create kar sake"
π€ Sochna Start:
ββ URL kya hoga?
β β /api/orders (resource name plural)
β
ββ HTTP method?
β β POST (kyunki create kar rahe)
β
ββ Input kahan se?
β β Request body se JSON (OrderRequest DTO)
β
ββ Authentication?
β β Haan, user login hona chahiye
β β User ID header se milega
β
ββ Response kya?
β β Created order details
β β Status: 201 Created
β
ββ Error handling?
β Validation fail? β 400
β Product not found? β 404
β Payment fail? β 422
π‘ STEP 4: Code Likhne Ka Actual Process
Step-by-Step Sochkar Code Likho:
@RestController
@RequestMapping("/api/orders")
public class OrderController {
// STEP 1: Dependencies sochna
// Kisko call karna padega?
// β Service layer (business logic)
// β Mapper (DTO to Entity conversion)
@Autowired
private OrderService orderService; // Business logic ke liye
@Autowired
private OrderMapper orderMapper; // DTO conversion ke liye
// STEP 2: Method signature sochna
// βββββββββββββββββββββββββββββββββββββββββββ
// β @PostMapping β kyunki CREATE operation β
// β ResponseEntity β control chahiye β
// β <ApiResponse<OrderResponse>> β wrapper β
// βββββββββββββββββββββββββββββββββββββββββββ
@PostMapping
public ResponseEntity<ApiResponse<OrderResponse>> createOrder(
// STEP 3: Parameters sochna - Kya kya chahiye?
// 3a. Order data β Request body se
@RequestBody @Valid OrderRequest request,
// 3b. User identification β Header se
@RequestHeader("X-User-Id") Long userId
// Yeh sochna: Aur kya chahiye?
// - Authentication token? (Spring Security handle karega)
// - Request ID for tracing? (optional)
) {
// STEP 4: Method body - Logic step by step
// 4a. INPUT VALIDATION (already @Valid se ho gaya)
// But extra business validation?
// 4b. LOGGING (debugging ke liye)
log.info("Creating order for user: {}", userId);
// 4c. DTO to ENTITY conversion
// Kyunki service ko entity chahiye, DTO nahi
Order order = orderMapper.toEntity(request);
order.setUserId(userId); // User ID set karna
// 4d. SERVICE CALL (actual business logic)
Order createdOrder = orderService.createOrder(order);
// 4e. ENTITY to DTO conversion
// Kyunki user ko DTO bhejenge, entity nahi
OrderResponse response = orderMapper.toResponse(createdOrder);
// 4f. RESPONSE WRAPPER
// Standard format mein return
ApiResponse<OrderResponse> apiResponse = ApiResponse.success(
"Order created successfully",
response
);
// 4g. RETURN with proper STATUS
return ResponseEntity
.status(HttpStatus.CREATED) // 201
.body(apiResponse);
}
}
π¨ STEP 5: Har Component Kyu Banana - Decision Tree
βββββββββββββββββββββββββββββββββββββββββββββββ
β Controller Method Banana β
ββββββββββββββββββββ¬βββββββββββββββββββββββββββ
β
ββββββββββββ΄βββββββββββ
β 1. HTTP Mapping? β
ββββββββββββ¬βββββββββββ
β
ββββββββββββΌβββββββββββββββββββββββ
β POST β Create (insert) β
β GET β Read (fetch) β
β PUT β Update (full) β
β PATCH β Update (partial) β
β DELETE β Delete (remove) β
ββββββββββββ¬βββββββββββββββββββββββ
β
ββββββββββββΌβββββββββββ
β 2. Input Source? β
ββββββββββββ¬βββββββββββ
β
ββββββββββββΌβββββββββββββββββββββββββ
β @RequestBody β JSON data β
β @PathVariable β URL mein {id} β
β @RequestParam β ?name=value β
β @RequestHeader β Headers β
ββββββββββββ¬βββββββββββββββββββββββββ
β
ββββββββββββΌβββββββββββ
β 3. Validation? β
ββββββββββββ¬βββββββββββ
β
ββββββββββββΌββββββββββββββββββββββ
β @Valid β DTO validation β
β @NotNull β Field level β
β Custom logic β Business rules β
ββββββββββββ¬ββββββββββββββββββββββ
β
ββββββββββββΌβββββββββββ
β 4. Processing? β
ββββββββββββ¬βββββββββββ
β
ββββββββββββΌβββββββββββββββββββββ
β Service call β Business logic β
β Repository β Direct DB (bad) β
ββββββββββββ¬βββββββββββββββββββββ
β
ββββββββββββΌβββββββββββ
β 5. Response? β
ββββββββββββ¬βββββββββββ
β
ββββββββββββΌβββββββββββββββββββββββ
β Object β Auto serialize β
β ResponseEntity β Control status β
β ApiResponse β Standard format β
βββββββββββββββββββββββββββββββββββ
π§© STEP 6: DTOs Kab Aur Kyu Banana
Decision Making:
// β BAD: Entity directly use
@PostMapping
public Order createOrder(@RequestBody Order order) {
return orderService.save(order);
}
// β
GOOD: DTO use karo
@PostMapping
public ResponseEntity<OrderResponse> createOrder(
@RequestBody OrderRequest request
) {
Order order = orderMapper.toEntity(request);
Order saved = orderService.save(order);
OrderResponse response = orderMapper.toResponse(saved);
return ResponseEntity.ok(response);
}
Kyu DTOs?
1. SECURITY
Entity mein sensitive fields ho sakte hain
(password, internal IDs, audit fields)
2. FLEXIBILITY
Database change ho, API same rahe
3. VALIDATION
Input aur output different validation
4. VERSIONING
API v1, v2 different DTOs use kar sakte
π§ STEP 7: Service Layer Ko Call Kaise Kare
Thinking Process:
// Controller ka kaam SIRF:
// 1. Request receive karna
// 2. Validation karna
// 3. Service ko call karna
// 4. Response return karna
@RestController
@RequestMapping("/api/products")
public class ProductController {
// Service inject karo (dependency)
@Autowired
private ProductService productService;
@GetMapping("/{id}")
public ResponseEntity<ProductResponse> getProduct(@PathVariable Long id) {
// β GALAT: Controller mein business logic
// Product product = productRepository.findById(id);
// if (product.getStock() > 0) {
// product.setAvailable(true);
// }
// β
SAHI: Service ko call karo
Product product = productService.getProductById(id);
ProductResponse response = productMapper.toResponse(product);
return ResponseEntity.ok(response);
}
}
π― STEP 8: Complete Example - Sochte Hue Likho
Requirement: User apne orders list dekhe with filters
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@Autowired
private OrderService orderService;
// SOCHNA START:
// ββββββββββββββββββββββββββββββββββββββββ
// GET method β read operation
// Pagination β large data ho sakta hai
// Filters β status, date range
// User-specific β userId header se
@GetMapping
public ResponseEntity<PageResponse<OrderResponse>> getMyOrders(
// USER IDENTIFICATION
@RequestHeader("X-User-Id") Long userId,
// PAGINATION PARAMETERS
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
// SORTING
@RequestParam(defaultValue = "createdAt") String sortBy,
@RequestParam(defaultValue = "DESC") String sortDirection,
// FILTERS (optional - required = false)
@RequestParam(required = false) String status,
@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate
) {
// STEP 1: Log the request
log.info("Fetching orders for user: {}, page: {}", userId, page);
// STEP 2: Validation (optional parameters check)
if (page < 0 || size <= 0 || size > 100) {
throw new InvalidRequestException("Invalid pagination parameters");
}
// STEP 3: Build filter object
// Kyunki bahut parameters hain, object mein wrap karo
OrderFilter filter = OrderFilter.builder()
.userId(userId)
.status(status)
.startDate(startDate)
.endDate(endDate)
.build();
// STEP 4: Build pagination object
PageRequest pageRequest = PageRequest.of(
page,
size,
Sort.by(Sort.Direction.fromString(sortDirection), sortBy)
);
// STEP 5: Service call
Page<Order> orderPage = orderService.getOrders(filter, pageRequest);
// STEP 6: Convert to DTO
List<OrderResponse> responses = orderPage.getContent()
.stream()
.map(orderMapper::toResponse)
.collect(Collectors.toList());
// STEP 7: Build page response
PageResponse<OrderResponse> pageResponse = PageResponse.<OrderResponse>builder()
.content(responses)
.pageNumber(orderPage.getNumber())
.pageSize(orderPage.getSize())
.totalElements(orderPage.getTotalElements())
.totalPages(orderPage.getTotalPages())
.build();
// STEP 8: Return with proper status
return ResponseEntity.ok(pageResponse);
}
}
π STEP 9: Decision Chart - Kya Use Karu?
Input Parameters Decision:
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Data kahan se aa raha hai? β
βββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β URL path mein? β
β /orders/123 β @PathVariable Long id β
β β
β Query string mein? β
β /orders?status=pending β @RequestParam String β
β β
β Request body mein? β
β JSON payload β @RequestBody OrderDTO β
β β
β Headers mein? β
β Authorization token β @RequestHeader String β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
Return Type Decision:
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Kya control chahiye? β
βββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Status code + headers + body? β
β β ResponseEntity<T> β
β β
β Sirf data return? β
β β Direct object (Spring auto-converts) β
β β
β Standard API format? β
β β ResponseEntity<ApiResponse<T>> β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
π STEP 10: Practice Pattern - Khud Se Code Karo
Template Follow Karo:
// TEMPLATE for any new endpoint:
@[HttpMethod]Mapping("[url-path]")
public ResponseEntity<ApiResponse<[ResponseDTO]>> methodName(
// 1. Identify karo - kya chahiye?
@PathVariable [Type] [name], // URL se ID
@RequestParam [Type] [name], // Query params
@RequestBody @Valid [RequestDTO] dto, // JSON body
@RequestHeader [Type] [name] // Headers
) {
// 2. Log karo
log.info("Doing something with: {}", name);
// 3. DTO to Entity (agar chahiye)
[Entity] entity = mapper.toEntity(dto);
// 4. Service call (business logic)
[Entity] result = service.doSomething(entity);
// 5. Entity to DTO
[ResponseDTO] response = mapper.toResponse(result);
// 6. Wrap in ApiResponse
ApiResponse<[ResponseDTO]> apiResponse =
ApiResponse.success("Success message", response);
// 7. Return with status
return ResponseEntity
.status(HttpStatus.[STATUS])
.body(apiResponse);
}
π₯ STEP 11: Common Patterns Yaad Rakho
CRUD Operations:
// CREATE
@PostMapping β @RequestBody β service.create() β 201 CREATED
// READ (single)
@GetMapping("/{id}") β @PathVariable β service.findById() β 200 OK
// READ (all)
@GetMapping β @RequestParam (filters) β service.findAll() β 200 OK
// UPDATE
@PutMapping("/{id}") β @PathVariable + @RequestBody β service.update() β 200 OK
// DELETE
@DeleteMapping("/{id}") β @PathVariable β service.delete() β 204 NO_CONTENT
πͺ Practice Exercise - Khud Karo:
Requirement: Product management system
TODO:
1. Product create karo (name, price, stock)
2. Products list fetch karo (with pagination)
3. Product by ID fetch karo
4. Product update karo
5. Product delete karo
Socho:
- Kis method mein kya parameters?
- Kis method mein kya validation?
- Kis method mein kya return type?
- Kis method mein kya status code?
Yeh pattern follow karo, 2-3 CRUD modules khud likho, sab clear ho jayega! π
Top comments (0)