Controller Mein Data Kab Aur Kaise Pass Kare - Crystal Clear Guide π―
Simple Rule: Sirf 4 Jagah Se Data Aata Hai
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β REQUEST KAHAN SE AA RAHA HAI? β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β 1. URL Path β @PathVariable β
β /users/123 β
β β
β 2. URL Query β @RequestParam β
β /users?name=Raj&age=25 β
β β
β 3. Request Body β @RequestBody β
β POST with JSON {"name": "Raj"} β
β β
β 4. Headers β @RequestHeader β
β Authorization: Bearer token123 β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Decision Tree - Kab Kya Use Kare
START: User ne request bheji
β
βββ Resource ka ID chahiye? (single item get/update/delete)
β βββ USE: @PathVariable
β Example: /users/123, /orders/456
β
βββ Filtering/Search/Pagination chahiye?
β βββ USE: @RequestParam
β Example: /users?age=25&city=Mumbai
β
βββ Complex data create/update karna hai?
β βββ USE: @RequestBody
β Example: POST /users with full JSON
β
βββ Authentication/Authorization check karna hai?
βββ USE: @RequestHeader
Example: Authorization token, User-ID
Pattern 1: GET - Single Item (By ID)
// USE CASE: Specific user ko fetch karna
// URL: GET /api/users/123
@GetMapping("/users/{id}")
public ResponseEntity<User> getUser(
@PathVariable Long id // β URL se ID
) {
User user = userService.findById(id);
return ResponseEntity.ok(user);
}
/*
WHY @PathVariable?
- ID URL mein hai: /users/123
- Mandatory hai (URL mein hona chahiye)
- Resource identify karne ke liye
*/
Pattern 2: GET - List with Filters
// USE CASE: Filter karke users chahiye
// URL: GET /api/users?age=25&city=Mumbai&active=true
@GetMapping("/users")
public ResponseEntity<List<User>> getUsers(
@RequestParam(required = false) Integer age, // β Optional filter
@RequestParam(required = false) String city, // β Optional filter
@RequestParam(defaultValue = "true") Boolean active // β Default value
) {
List<User> users = userService.findByFilters(age, city, active);
return ResponseEntity.ok(users);
}
/*
WHY @RequestParam?
- Data ? ke baad hai (query string)
- Optional ho sakta hai
- Multiple filters
- Pagination/sorting ke liye
*/
Pattern 3: GET - Pagination
// USE CASE: Page by page data chahiye
// URL: GET /api/users?page=0&size=20&sortBy=name
@GetMapping("/users")
public ResponseEntity<Page<User>> getUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size,
@RequestParam(defaultValue = "id") String sortBy
) {
Pageable pageable = PageRequest.of(page, size, Sort.by(sortBy));
Page<User> users = userService.findAll(pageable);
return ResponseEntity.ok(users);
}
/*
WHY @RequestParam?
- Pagination info query string mein hoti hai
- Optional with defaults
- Standard practice
*/
Pattern 4: POST - Create New Item
// USE CASE: Naya user create karna
// URL: POST /api/users
// Body: {"name": "Raj", "email": "raj@email.com", "age": 25}
@PostMapping("/users")
public ResponseEntity<User> createUser(
@RequestBody User user // β JSON body se data
) {
User created = userService.save(user);
return ResponseEntity.status(HttpStatus.CREATED).body(created);
}
/*
WHY @RequestBody?
- Complex data (multiple fields)
- JSON format mein data
- POST/PUT/PATCH operations
- Cannot use query params for complex objects
*/
Pattern 5: POST - With Validation
// USE CASE: Validation ke saath create
// URL: POST /api/users
// Body: {"name": "Raj", "email": "raj@email.com"}
@PostMapping("/users")
public ResponseEntity<User> createUser(
@Valid @RequestBody UserRequest request // β @Valid for validation
) {
User user = userMapper.toEntity(request);
User created = userService.save(user);
return ResponseEntity.status(HttpStatus.CREATED).body(created);
}
// UserRequest DTO
@Data
public class UserRequest {
@NotBlank(message = "Name is required")
private String name;
@Email(message = "Invalid email")
private String email;
@Min(value = 18, message = "Age must be 18+")
private Integer age;
}
/*
WHY @RequestBody with @Valid?
- Input validation automatically
- Clean separation (DTO vs Entity)
- Type safety
*/
Pattern 6: PUT - Update Existing Item
// USE CASE: User update karna (ID se identify + data se update)
// URL: PUT /api/users/123
// Body: {"name": "Updated Name", "email": "new@email.com"}
@PutMapping("/users/{id}")
public ResponseEntity<User> updateUser(
@PathVariable Long id, // β Which user
@RequestBody UserRequest request // β Updated data
) {
User updated = userService.update(id, request);
return ResponseEntity.ok(updated);
}
/*
WHY @PathVariable + @RequestBody?
- @PathVariable: Which resource to update (ID)
- @RequestBody: What to update (new data)
- Dono chaiye update ke liye
*/
Pattern 7: PATCH - Partial Update
// USE CASE: Sirf kuch fields update karne hain
// URL: PATCH /api/users/123
// Body: {"email": "newemail@email.com"} β Only email update
@PatchMapping("/users/{id}")
public ResponseEntity<User> partialUpdate(
@PathVariable Long id,
@RequestBody Map<String, Object> updates // β Flexible updates
) {
User updated = userService.partialUpdate(id, updates);
return ResponseEntity.ok(updated);
}
/*
WHY Map<String, Object>?
- Don't know which fields will be updated
- Flexible partial updates
- Only send changed fields
*/
Pattern 8: DELETE - Remove Item
// USE CASE: User delete karna
// URL: DELETE /api/users/123
@DeleteMapping("/users/{id}")
public ResponseEntity<Void> deleteUser(
@PathVariable Long id // β Which user to delete
) {
userService.delete(id);
return ResponseEntity.noContent().build(); // 204 No Content
}
/*
WHY only @PathVariable?
- Sirf ID chahiye delete ke liye
- No body needed
- Simple operation
*/
Pattern 9: Authentication Header
// USE CASE: Login required API
// URL: GET /api/profile
// Header: Authorization: Bearer token123
@GetMapping("/profile")
public ResponseEntity<User> getProfile(
@RequestHeader("Authorization") String token // β Auth token
) {
User user = userService.getByToken(token);
return ResponseEntity.ok(user);
}
/*
WHY @RequestHeader?
- Authentication token headers mein hota hai
- Security standard
- Every request mein chahiye
*/
Pattern 10: Multiple Headers
// USE CASE: Auth + User context
// URL: POST /api/orders
// Headers:
// Authorization: Bearer token123
// X-User-Id: 456
@PostMapping("/orders")
public ResponseEntity<Order> createOrder(
@RequestHeader("Authorization") String token,
@RequestHeader("X-User-Id") Long userId,
@RequestBody OrderRequest request
) {
validateToken(token);
Order order = orderService.create(userId, request);
return ResponseEntity.status(HttpStatus.CREATED).body(order);
}
/*
WHY Multiple Headers?
- Authorization: Token validation
- X-User-Id: User context
- Common in microservices
*/
Pattern 11: Complex Search (All 4 Together)
// USE CASE: Category ki products search with filters
// URL: GET /api/categories/electronics/products?minPrice=1000&page=0
// Header: X-User-Id: 123
@GetMapping("/categories/{category}/products")
public ResponseEntity<Page<Product>> searchProducts(
// 1. PATH VARIABLE - Category identify
@PathVariable String category,
// 2. REQUEST PARAM - Filters & pagination
@RequestParam(required = false) BigDecimal minPrice,
@RequestParam(required = false) BigDecimal maxPrice,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size,
// 3. HEADER - User context
@RequestHeader("X-User-Id") Long userId
) {
Pageable pageable = PageRequest.of(page, size);
Page<Product> products = productService.searchInCategory(
category, minPrice, maxPrice, userId, pageable
);
return ResponseEntity.ok(products);
}
/*
WHY All Together?
- @PathVariable: Category (resource)
- @RequestParam: Filters (optional search criteria)
- @RequestHeader: User context (auth/personalization)
*/
Pattern 12: File Upload
// USE CASE: Profile picture upload
// URL: POST /api/users/123/avatar
// Body: multipart/form-data with file
@PostMapping("/users/{id}/avatar")
public ResponseEntity<String> uploadAvatar(
@PathVariable Long id,
@RequestParam("file") MultipartFile file // β File from form-data
) {
String avatarUrl = fileService.uploadFile(file);
userService.updateAvatar(id, avatarUrl);
return ResponseEntity.ok(avatarUrl);
}
/*
WHY @RequestParam for file?
- File form-data mein aati hai
- MultipartFile type
- Standard practice for file uploads
*/
Quick Decision Table
| Scenario | Annotation | Example URL | Example Code |
|---|---|---|---|
| Get by ID | @PathVariable |
/users/123 |
getUser(@PathVariable Long id) |
| Search/Filter | @RequestParam |
/users?age=25 |
search(@RequestParam Integer age) |
| Create | @RequestBody |
POST /users + JSON |
create(@RequestBody User user) |
| Update |
@PathVariable + @RequestBody
|
PUT /users/123 + JSON |
update(@PathVariable Long id, @RequestBody User user) |
| Delete | @PathVariable |
DELETE /users/123 |
delete(@PathVariable Long id) |
| Auth | @RequestHeader |
Header: Authorization
|
get(@RequestHeader String token) |
| Pagination | @RequestParam |
/users?page=0&size=20 |
list(@RequestParam int page) |
| File Upload | @RequestParam |
POST /upload |
upload(@RequestParam MultipartFile file) |
Common Mistakes - Mat Karna
// β WRONG: Body ke jagah PathVariable
@PostMapping("/users/{user}")
public User create(@PathVariable User user) { }
// Galat! Complex object path mein nahi aata
// β
RIGHT: Body use karo
@PostMapping("/users")
public User create(@RequestBody User user) { }
// β WRONG: Multiple filters PathVariable se
@GetMapping("/users/{age}/{city}")
public List<User> search(@PathVariable int age, @PathVariable String city) { }
// Ugly URL: /users/25/Mumbai
// β
RIGHT: RequestParam use karo
@GetMapping("/users")
public List<User> search(@RequestParam int age, @RequestParam String city) { }
// Clean URL: /users?age=25&city=Mumbai
// β WRONG: ID ko RequestParam
@GetMapping("/users")
public User getUser(@RequestParam Long id) { }
// URL: /users?id=123 (weird)
// β
RIGHT: ID ko PathVariable
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) { }
// URL: /users/123 (clean)
Final Summary - Ek Line Mein:
ID hai? β @PathVariable (/users/123)
Filter/Search hai? β @RequestParam (/users?age=25)
JSON body hai? β @RequestBody (POST with {...})
Auth/Token hai? β @RequestHeader (Authorization: ...)
Bas yeh 4 rules yaad rakho, confusion khatam! π
Top comments (0)