← Назад к вопросам
Как написать RESTful приложение для чтения данных из базы данных
2.2 Middle🔥 241 комментариев
#REST API и микросервисы#Spring Framework#ООП
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как написать RESTful приложение для чтения данных из базы данных
Расскажу полный пример создания RESTful приложения с соблюдением best practices.
1. Domain Layer
@Value
public class User {
Long id;
String email;
String name;
int age;
public boolean isAdult() {
return age >= 18;
}
}
public interface UserRepository {
Optional<User> findById(Long id);
List<User> findAll();
Page<User> findAllPaged(int page, int size);
}
2. Infrastructure - JPA Entity
@Entity
@Table(name = "users")
@Data
public class UserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String email;
private String name;
private int age;
}
@Repository
public interface UserJpaRepository extends JpaRepository<UserEntity, Long> {
Optional<UserEntity> findByEmail(String email);
}
3. Adapter реализация
@Repository
@RequiredArgsConstructor
public class UserRepositoryAdapter implements UserRepository {
private final UserJpaRepository jpaRepository;
private final UserMapper mapper;
@Override
public Optional<User> findById(Long id) {
return jpaRepository.findById(id).map(mapper::toDomain);
}
@Override
public List<User> findAll() {
return jpaRepository.findAll().stream()
.map(mapper::toDomain)
.collect(Collectors.toList());
}
@Override
public Page<User> findAllPaged(int page, int size) {
return jpaRepository.findAll(PageRequest.of(page, size))
.map(mapper::toDomain);
}
}
4. Service Layer
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final UserMapper mapper;
public UserDTO getUserById(Long id) {
return userRepository.findById(id)
.map(mapper::toDTO)
.orElseThrow(() -> new UserNotFoundException("User not found"));
}
public Page<UserDTO> getUsersPaged(int page, int size) {
return userRepository.findAllPaged(page, size)
.map(mapper::toDTO);
}
}
5. REST Controller
@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping("/{id}")
public ResponseEntity<UserDTO> getUserById(@PathVariable Long id) {
return ResponseEntity.ok(userService.getUserById(id));
}
@GetMapping
public ResponseEntity<Page<UserDTO>> getAllUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size) {
return ResponseEntity.ok(userService.getUsersPaged(page, size));
}
}
6. Exception Handling
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse> handleUserNotFound(
UserNotFoundException ex) {
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse("USER_NOT_FOUND", ex.getMessage()));
}
}
Best Practices
- Layered Architecture: Domain → Application → Infrastructure → Presentation
- No trailing slashes:
/api/v1/usersне/api/v1/users/ - Правильные HTTP статусы: 200, 404, 500
- Пагинация для больших наборов
- Read-only транзакции для чтения
- DTO вместо Entity в API
- Логирование на каждом слое