Bu bo‘limda Spring Boot’da birinchi haqiqiy REST API yozishni o‘rganamiz. Bu mavzu ichida @RestController, @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PathVariable, @RequestParam, @RequestBody, ResponseEntity va HTTP status codes bor.
1. REST API nima?
REST API - frontend, mobile app yoki boshqa servis backend bilan gaplashishi uchun ishlatiladigan HTTP API.
Masalan, mobil app backenddan userlar ro‘yxatini so‘raydi:
GET /usersBackend javob qaytaradi:
[
{
"id": 1,
"name": "Ali"
},
{
"id": 2,
"name": "Vali"
}
]Oddiy qilib:
REST API - client va server o‘rtasidagi kelishilgan HTTP muloqot.
2. REST API qayerda ishlatiladi?
Masalan:
Android app → Spring Boot API
iOS app → Spring Boot API
React app → Spring Boot API
Telegram bot → Spring Boot API
Boshqa microservice → Spring Boot APIBackend odatda JSON qaytaradi.
3. HTTP methodlar
REST API’da eng ko‘p ishlatiladigan methodlar:
Method | Vazifasi | Misol |
|---|---|---|
| Ma’lumot olish | Userlarni olish |
| Yangi ma’lumot yaratish | Yangi user qo‘shish |
| Ma’lumotni to‘liq yangilash | Userni update qilish |
| Qisman yangilash | Faqat phone numberni update qilish |
| Ma’lumot o‘chirish | Userni o‘chirish |
4. Birinchi controller
Spring Boot’da REST API yozish uchun @RestController ishlatiladi.
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Salom Spring Boot";
}
}Brauzerda ochamiz:
http://localhost:8080/helloNatija:
Salom Spring Boot5. @RestController nima?
@RestController - bu class REST API controller ekanini bildiradi.
Ya’ni:
@RestController
public class UserController {
}Spring bu classni HTTP request qabul qiladigan controller sifatida ko‘radi.
Muhim jihati:
@RestControllermethoddan qaytgan qiymatni avtomatik HTTP response body qilib beradi.
Masalan:
@GetMapping("/name")
public String name() {
return "Ali";
}Javob body:
Ali6. @RequestMapping nima?
@RequestMapping umumiy path berish uchun ishlatiladi.
Masalan:
@RestController
@RequestMapping("/users")
public class UserController {
}Endi shu controller ichidagi hamma endpoint /users bilan boshlanadi.
@GetMapping
public String getUsers() {
return "Users list";
}Full path:
GET /users7. @GetMapping
GET - ma’lumot olish uchun.
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping
public String getUsers() {
return "Userlar ro'yxati";
}
}Request:
GET /usersResponse:
Userlar ro'yxati8. @PostMapping
POST - yangi ma’lumot yaratish uchun.
@PostMapping
public String createUser() {
return "User yaratildi";
}Request:
POST /usersResponse:
User yaratildiLekin real loyihada POST odatda body bilan keladi.
9. @PutMapping
PUT - mavjud ma’lumotni yangilash uchun.
@PutMapping("/{id}")
public String updateUser(@PathVariable Long id) {
return "User yangilandi: " + id;
}Request:
PUT /users/5Response:
User yangilandi: 510. @DeleteMapping
DELETE - ma’lumotni o‘chirish uchun.
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable Long id) {
return "User o'chirildi: " + id;
}Request:
DELETE /users/5Response:
User o'chirildi: 511. To‘liq CRUD endpointlar
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping
public String getUsers() {
return "Barcha userlar";
}
@GetMapping("/{id}")
public String getUserById(@PathVariable Long id) {
return "User ID: " + id;
}
@PostMapping
public String createUser() {
return "User yaratildi";
}
@PutMapping("/{id}")
public String updateUser(@PathVariable Long id) {
return "User yangilandi: " + id;
}
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable Long id) {
return "User o'chirildi: " + id;
}
}Endpointlar:
GET /users
GET /users/1
POST /users
PUT /users/1
DELETE /users/112. @PathVariable nima?
@PathVariable - URL ichidagi qiymatni olish uchun ishlatiladi.
Masalan:
GET /users/10Bu yerda 10 - path variable.
Kod:
@GetMapping("/{id}")
public String getUser(@PathVariable Long id) {
return "User ID: " + id;
}Natija:
User ID: 10@PathVariable nomi boshqacha bo‘lsa
@GetMapping("/{userId}")
public String getUser(@PathVariable Long userId) {
return "User ID: " + userId;
}Yoki aniq ko‘rsatish mumkin:
@GetMapping("/{id}")
public String getUser(@PathVariable("id") Long userId) {
return "User ID: " + userId;
}13. @RequestParam nima?
@RequestParam - URL query parameter olish uchun ishlatiladi.
Masalan:
GET /users?name=AliKod:
@GetMapping("/search")
public String searchUser(@RequestParam String name) {
return "Qidirilgan user: " + name;
}Request:
GET /users/search?name=AliResponse:
Qidirilgan user: AliBir nechta @RequestParam
GET /users/search?name=Ali&age=25@GetMapping("/search")
public String searchUser(
@RequestParam String name,
@RequestParam Integer age
) {
return name + " - " + age;
}Optional @RequestParam
Agar parameter kelmasa ham xato bermasin desak:
@GetMapping("/search")
public String searchUser(
@RequestParam(required = false) String name
) {
return "Name: " + name;
}Default qiymat berish:
@GetMapping("/search")
public String searchUser(
@RequestParam(defaultValue = "unknown") String name
) {
return "Name: " + name;
}14. @PathVariable vs @RequestParam
Turi | Qayerdan oladi? | Misol |
|---|---|---|
| URL path ichidan |
|
| Query parameterdan |
|
Qachon qaysi biri?
/users/5 → aniq bitta user olish → @PathVariable
/users?name=Ali → filter/search qilish → @RequestParam
/users?page=1&size=20 → pagination → @RequestParam15. @RequestBody nima?
@RequestBody - HTTP request body ichidagi JSON’ni Java objectga aylantirib beradi.
Masalan frontend shunday JSON yuboradi:
{
"name": "Ali",
"age": 25
}Biz Java’da DTO class yozamiz:
public class CreateUserRequest {
private String name;
private Integer age;
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
}Controller:
@PostMapping
public String createUser(@RequestBody CreateUserRequest request) {
return "User yaratildi: " + request.getName();
}Request:
POST /users
Content-Type: application/jsonBody:
{
"name": "Ali",
"age": 25
}Response:
User yaratildi: Ali16. Lombok bilan DTO
Agar Lombok ishlatsak:
@Getter
@Setter
public class CreateUserRequest {
private String name;
private Integer age;
}Yoki Java record:
public record CreateUserRequest(
String name,
Integer age
) {
}Spring Boot’da record DTO uchun juda qulay.
17. Response object qaytarish
Text emas, object qaytarsak, Spring avtomatik JSON qiladi.
public record UserResponse(
Long id,
String name,
Integer age
) {
}Controller:
@GetMapping("/{id}")
public UserResponse getUser(@PathVariable Long id) {
return new UserResponse(id, "Ali", 25);
}Response:
{
"id": 1,
"name": "Ali",
"age": 25
}18. List qaytarish
@GetMapping
public List<UserResponse> getUsers() {
return List.of(
new UserResponse(1L, "Ali", 25),
new UserResponse(2L, "Vali", 30)
);
}Response:
[
{
"id": 1,
"name": "Ali",
"age": 25
},
{
"id": 2,
"name": "Vali",
"age": 30
}
]19. ResponseEntity nima?
ResponseEntity - HTTP response’ni to‘liq nazorat qilish uchun ishlatiladi.
U orqali quyidagilarni belgilaymiz:
Response body
HTTP status code
HeaderOddiy misol:
@GetMapping("/{id}")
public ResponseEntity<UserResponse> getUser(@PathVariable Long id) {
UserResponse response = new UserResponse(id, "Ali", 25);
return ResponseEntity.ok(response);
}Bu:
HTTP status: 200 OK
Body: user JSON20. 201 Created qaytarish
Yangi resource yaratilganda 201 Created qaytarish yaxshi.
@PostMapping
public ResponseEntity<UserResponse> createUser(
@RequestBody CreateUserRequest request
) {
UserResponse response = new UserResponse(1L, request.name(), request.age());
return ResponseEntity
.status(HttpStatus.CREATED)
.body(response);
}Response:
HTTP status: 201 CreatedBody:
{
"id": 1,
"name": "Ali",
"age": 25
}21. 204 No Content qaytarish
Delete qilinganda ko‘pincha body qaytarilmaydi.
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
return ResponseEntity.noContent().build();
}Response:
HTTP status: 204 No Content
Body yo‘q22. HTTP status codes
Eng kerakli statuslar:
Status | Nomi | Qachon ishlatiladi? |
|---|---|---|
| OK | Muvaffaqiyatli GET/PUT |
| Created | Yangi ma’lumot yaratildi |
| No Content | Muvaffaqiyatli, lekin body yo‘q |
| Bad Request | Noto‘g‘ri request |
| Unauthorized | Login qilmagan |
| Forbidden | Ruxsat yo‘q |
| Not Found | Ma’lumot topilmadi |
| Conflict | Ma’lumot conflict bo‘ldi |
| Internal Server Error | Server ichki xatosi |
23. To‘liq mini REST API
UserResponse
public record UserResponse(
Long id,
String name,
Integer age
) {
}CreateUserRequest
public record CreateUserRequest(
String name,
Integer age
) {
}UserController
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping
public List<UserResponse> getUsers() {
return List.of(
new UserResponse(1L, "Ali", 25),
new UserResponse(2L, "Vali", 30)
);
}
@GetMapping("/{id}")
public ResponseEntity<UserResponse> getUser(@PathVariable Long id) {
UserResponse response = new UserResponse(id, "Ali", 25);
return ResponseEntity.ok(response);
}
@PostMapping
public ResponseEntity<UserResponse> createUser(
@RequestBody CreateUserRequest request
) {
UserResponse response = new UserResponse(3L, request.name(), request.age());
return ResponseEntity
.status(HttpStatus.CREATED)
.body(response);
}
@PutMapping("/{id}")
public ResponseEntity<UserResponse> updateUser(
@PathVariable Long id,
@RequestBody CreateUserRequest request
) {
UserResponse response = new UserResponse(id, request.name(), request.age());
return ResponseEntity.ok(response);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
return ResponseEntity.noContent().build();
}
}24. Postman yoki browser orqali test
Browser bilan
Browser faqat GET endpointlarni oson test qiladi:
http://localhost:8080/users
http://localhost:8080/users/1Postman bilan
POST, PUT, DELETE uchun Postman ishlatish qulay.
POST request:
POST http://localhost:8080/users
Content-Type: application/jsonBody:
{
"name": "Hasan",
"age": 22
}Expected response:
{
"id": 3,
"name": "Hasan",
"age": 22
}Status:
201 Created25. curl bilan test
Terminalda:
curl http://localhost:8080/usersPOST:
curl -X POST http://localhost:8080/users \
-H "Content-Type: application/json" \
-d '{"name":"Hasan","age":22}'PUT:
curl -X PUT http://localhost:8080/users/1 \
-H "Content-Type: application/json" \
-d '{"name":"Ali Updated","age":26}'DELETE:
curl -X DELETE http://localhost:8080/users/126. Controller → Service → Repository qilish
Bo'shlanishiga controller ichida hamma narsani yozib ketish mumkin, lekin real loyihada bu noto‘g‘ri.
Yaxshi structure:
controller → service → repositoryMasalan:
UserController request oladi
UserService biznes logika bajaradi
UserRepository data bilan ishlaydiUserService
@Service
public class UserService {
public List<UserResponse> getUsers() {
return List.of(
new UserResponse(1L, "Ali", 25),
new UserResponse(2L, "Vali", 30)
);
}
public UserResponse getUser(Long id) {
return new UserResponse(id, "Ali", 25);
}
public UserResponse createUser(CreateUserRequest request) {
return new UserResponse(3L, request.name(), request.age());
}
}UserController
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping
public List<UserResponse> getUsers() {
return userService.getUsers();
}
@GetMapping("/{id}")
public ResponseEntity<UserResponse> getUser(@PathVariable Long id) {
return ResponseEntity.ok(userService.getUser(id));
}
@PostMapping
public ResponseEntity<UserResponse> createUser(
@RequestBody CreateUserRequest request
) {
return ResponseEntity
.status(HttpStatus.CREATED)
.body(userService.createUser(request));
}
}Bu yaxshiroq, chunki controller faqat request/response bilan ishlaydi.
27. Eng ko‘p xatolar
1. @RestController yozmaslik
Xato:
public class UserController {
}To‘g‘ri:
@RestController
public class UserController {
}2. @RequestBody unutish
Xato:
@PostMapping
public String createUser(CreateUserRequest request) {
return request.name();
}To‘g‘ri:
@PostMapping
public String createUser(@RequestBody CreateUserRequest request) {
return request.name();
}3. Content-Type bermaslik
POST request yuborganda header kerak:
Content-Type: application/jsonAks holda Spring body’ni to‘g‘ri o‘qimasligi mumkin.
4. Path nomlari chalkashishi
Xato:
@GetMapping("/{id}")
public String getUser(@PathVariable Long userId) {
return userId.toString();
}Bu holatda Spring ba’zan id bilan userIdni moslay olmaydi.
To‘g‘ri:
@GetMapping("/{id}")
public String getUser(@PathVariable("id") Long userId) {
return userId.toString();
}28. REST API naming qoidalari
Yaxshi endpointlar:
GET /users
GET /users/1
POST /users
PUT /users/1
DELETE /users/1Yomonroq endpointlar:
GET /getUsers
POST /createUser
POST /deleteUser
GET /userDeleteREST’da odatda fe’l emas, resource nomi ishlatiladi:
/users
/products
/orders
/paymentsAmalni HTTP method bildiradi:
GET → olish
POST → yaratish
PUT → yangilash
DELETE → o‘chirish29. Interview uchun javoblar
Savol: @RestController nima?
@RestControllerSpring’da REST API controller yaratish uchun ishlatiladi. U methoddan qaytgan qiymatni avtomatik HTTP response body qilib qaytaradi.
Savol: @PathVariable va @RequestParam farqi?
@PathVariableURL path ichidagi qiymatni oladi, masalan/users/1.@RequestParamesa query parameter oladi, masalan/users?name=Ali.
Savol: @RequestBody nima?
@RequestBodyHTTP request body ichidagi JSON’ni Java obyektga convert qilib beradi.
Savol: ResponseEntity nima uchun kerak?
ResponseEntityresponse body, HTTP status code va headerlarni boshqarish uchun kerak.
30. Bo'shlangich java developer uchun xulosa
Bugungi mavzudan eslab qoling:
@RestController - REST API controller
@RequestMapping - umumiy path
@GetMapping - ma’lumot olish
@PostMapping - yangi ma’lumot yaratish
@PutMapping - ma’lumot yangilash
@DeleteMapping - ma’lumot o‘chirish
@PathVariable - URL pathdan qiymat olish
@RequestParam - query parameter olish
@RequestBody - JSON body olish
ResponseEntity - status/body/header boshqarish31. Amaliy vazifa
Product API yoz:
GET /products
GET /products/1
POST /products
PUT /products/1
DELETE /products/1DTO:
public record ProductRequest(
String name,
Double price
) {
}Response:
public record ProductResponse(
Long id,
String name,
Double price
) {
}Controller service orqali ishlasin:
ProductController → ProductService