Gymterview
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 для валидации.