1. Спроектировать и реализовать REST API для управления пользователем
Условие задачи:
Необходимо спроектировать REST API для управления пользователями.
API должно поддерживать:
создание пользователя;
получение пользователя по
id;получение списка пользователей;
обновление пользователя;
удаление пользователя.
Данные можно хранить в памяти.
Код:
public class User {
private Long id;
private String name;
private String email;
private Integer age;
// getters / setters / constructors
}
Спойлеры к решению
Подсказки
💡 Используй
💡 Логику работы с пользователями вынеси в
💡 Для хранения в памяти подойдёт
💡 Для генерации идентификаторов можно использовать
💡 Для входных данных удобно использовать отдельный DTO с валидацией.
💡 Если пользователь не найден, возвращай
@RestController и HTTP-методы POST, GET, PUT, DELETE.💡 Логику работы с пользователями вынеси в
@Service.💡 Для хранения в памяти подойдёт
ConcurrentHashMap.💡 Для генерации идентификаторов можно использовать
AtomicLong.💡 Для входных данных удобно использовать отдельный DTO с валидацией.
💡 Если пользователь не найден, возвращай
404 Not Found.Решение
DTO для входных данных:
public record UserRequest(
@NotBlank String name,
@NotBlank @Email String email,
@Min(0) Integer age
) {
}
Модель:
public record User(
Long id,
String name,
String email,
Integer age
) {
}
Сервис:
@Service
public class UserService {
private final Map<Long, User> users =
new ConcurrentHashMap<>();
private final AtomicLong idGenerator =
new AtomicLong();
public User create(UserRequest request) {
long id = idGenerator.incrementAndGet();
User user = new User(
id,
request.name(),
request.email(),
request.age()
);
users.put(id, user);
return user;
}
public User getById(long id) {
User user = users.get(id);
if (user == null) {
throw new NoSuchElementException(
"User not found: " + id
);
}
return user;
}
public List<User> getAll() {
return users.values().stream()
.sorted(Comparator.comparing(User::id))
.toList();
}
public User update(
long id,
UserRequest request
) {
if (!users.containsKey(id)) {
throw new NoSuchElementException(
"User not found: " + id
);
}
User updated = new User(
id,
request.name(),
request.email(),
request.age()
);
users.put(id, updated);
return updated;
}
public void delete(long id) {
if (users.remove(id) == null) {
throw new NoSuchElementException(
"User not found: " + id
);
}
}
}
Контроллер:
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public User create(
@Valid @RequestBody UserRequest request
) {
return userService.create(request);
}
@GetMapping("/{id}")
public User getById(
@PathVariable long id
) {
return userService.getById(id);
}
@GetMapping
public List<User> getAll() {
return userService.getAll();
}
@PutMapping("/{id}")
public User update(
@PathVariable long id,
@Valid @RequestBody UserRequest request
) {
return userService.update(id, request);
}
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void delete(
@PathVariable long id
) {
userService.delete(id);
}
}
Обработка 404:
@RestControllerAdvice
public class ApiExceptionHandler {
@ExceptionHandler(NoSuchElementException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handleNotFound(
NoSuchElementException exception
) {
return exception.getMessage();
}
}
Получившийся API:
POST /api/users
GET /api/users/{id}
GET /api/users
PUT /api/users/{id}
DELETE /api/users/{id}
Для реального приложения хранилище в памяти можно заменить на JpaRepository, не меняя контракт контроллера.