junior
Как реализовать REST API в Spring?
Spring предоставляет средства для создания REST API через Spring Web MVC и Spring WebFlux (реактивный подход). Ключевые аннотации: @RestController (= @Controller + @ResponseBody), @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @PatchMapping, @DeleteMapping.
Полный пример CRUD-контроллера
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
@Validated
public class UserController {
private final UserService userService;
@GetMapping
public ResponseEntity<Page<UserDto>> getAllUsers(
@RequestParam(required = false) String name,
@PageableDefault(size = 20) Pageable pageable) {
Page<UserDto> users = userService.findAll(name, pageable);
return ResponseEntity.ok(users);
}
@GetMapping("/{id}")
public ResponseEntity<UserDto> getUser(@PathVariable Long id) {
UserDto user = userService.findById(id);
return ResponseEntity.ok(user);
}
@PostMapping
public ResponseEntity<UserDto> createUser(
@Valid @RequestBody CreateUserRequest request) {
UserDto created = userService.create(request);
URI location = ServletUriComponentsBuilder
.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(created.id())
.toUri();
return ResponseEntity.created(location).body(created);
}
@PutMapping("/{id}")
public ResponseEntity<UserDto> replaceUser(
@PathVariable Long id,
@Valid @RequestBody UpdateUserRequest request) {
UserDto updated = userService.replace(id, request);
return ResponseEntity.ok(updated);
}
@PatchMapping("/{id}")
public ResponseEntity<UserDto> updateUser(
@PathVariable Long id,
@RequestBody Map<String, Object> updates) {
UserDto updated = userService.partialUpdate(id, updates);
return ResponseEntity.ok(updated);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.delete(id);
return ResponseEntity.noContent().build();
}
}
Основные аннотации для параметров
| Аннотация | Назначение | Пример |
|---|---|---|
@PathVariable |
Извлечение из URI | /users/{id} |
@RequestParam |
Из query-строки | /users?name=Иван |
@RequestBody |
Десериализация тела запроса | JSON в объект |
@RequestHeader |
Извлечение HTTP-заголовка | Authorization |
@CookieValue |
Извлечение значения из cookie |
DTO, валидация и сервисный слой
public record CreateUserRequest(
@NotBlank(message = "Имя не может быть пустым")
String name,
@Email(message = "Некорректный формат email")
@NotBlank
String email,
@Min(value = 18, message = "Минимальный возраст — 18 лет")
Integer age
) {}
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class UserService {
private final UserRepository userRepository;
private final UserMapper userMapper;
public UserDto findById(Long id) {
return userRepository.findById(id)
.map(userMapper::toDto)
.orElseThrow(() ->
new EntityNotFoundException("Пользователь с id=" + id + " не найден"));
}
@Transactional
public UserDto create(CreateUserRequest request) {
User user = userMapper.toEntity(request);
User saved = userRepository.save(user);
return userMapper.toDto(saved);
}
}
На собеседовании: нужно показать знание основных аннотаций и структуру Controller → Service → Repository. Частая ошибка — не использовать DTO (работать с сущностями напрямую в контроллере) или забыть про
@Validдля валидации.