Изоляция данных и Feign: архитектура без сквозных связей
В микросервисной архитектуре важнейшим принципом является изоляция данных. Каждый сервис должен быть независимым и автономным: он владеет своей базой данных, управляет своим доменом и не зависит от внутренних деталей других сервисов — ни на уровне кода, ни на уровне БД.
Но как тогда один сервис может узнать что-то о другом? Ответ — через внешний API. И в мире Spring Boot для этого удобно использовать FeignClient.
Почему нельзя связывать микросервисы через JPA
Рассмотрим пример. У нас есть два сервиса:
courses-service
— управляет курсами и уроками.content-service
— отвечает за хранение медиафайлов, например видео-лекций.
В Lesson
из courses-service
может быть ссылка на контент. Но мы не должны делать это так:
1
2
3
@OneToOne
@JoinColumn(name = "content_item_id")
private ContentItem contentItem;
Это создает сквозную зависимость по JPA:
courses-service
становится зависим отcontent-service
;- нельзя запустить сервис без наличия структуры чужой БД;
- нарушается граница между доменами;
Как правильно
Вместо этого мы просто храним внешний идентификатор:
1
private UUID contentItemId;
И при необходимости получаем информацию о контенте через Feign:
1
2
3
4
5
6
@FeignClient(name = "content-service")
public interface ContentClient {
@GetMapping("/api/content/{id}")
ContentItemDTO getById(@PathVariable UUID id);
}
Таким образом:
- база
courses-service
остается чистой и независимой; - никаких внешних JOIN;
- взаимодействие идет через стабильный API.
Каждый сервис — отдельный мир
Это касается не только контента. Например, profiles-service
управляет пользователями, courses-service
может ссылаться на profileId
, но не должен знать, как устроена таблица профилей.
Если нужно получить данные профиля — используем ProfileClient
с Feign:
1
2
3
4
5
6
@FeignClient(name = "profiles-service")
public interface ProfileClient {
@GetMapping("/api/profiles/{id}")
ProfileDTO getProfile(@PathVariable UUID id);
}
Принципы слабой связанности
Принцип | Почему это важно |
---|---|
У каждого сервиса — своя БД | Независимость, масштабируемость |
Только DTO между сервисами | Четкие границы, простота изменений |
JPA-связи только внутри сервиса | Контроль и модульность |
REST/Feign между сервисами | Гибкость, устойчивость |
Статьи серии
- Микросервисы: серия материалов о принципах, паттернах и практике
- Эволюция архитектур: от монолита к микросервисам
- Микросервисная архитектура
- Нужен ли Service Discovery в Docker-среде?
- Вызов других микросервисов с помощью Feign
- Как работает Service Discovery в Spring Cloud и зачем он нужен
- API Gateway в микросервисной архитектуре
- (в разработке)