Связь между ограниченными контекстами: методы и примеры для микросервисов

«Связь между ограниченными контекстами может быть инициирована из разных источников».

При работе с архитектурой микросервисов обычно имеется несколько ограниченных контекстов, каждый из которых представляет отдельный домен в системе. Этим ограниченным контекстам может потребоваться взаимодействовать друг с другом для обмена информацией или запуска определенных действий. В этой статье мы рассмотрим несколько методов запуска связи между ограниченными контекстами, а также приведем примеры кода.

  1. Синхронные HTTP-запросы.
    Один из самых простых способов инициировать связь между ограниченными контекстами — это синхронные HTTP-запросы. В этом подходе один ограниченный контекст напрямую вызывает конечную точку API, предоставляемую другим ограниченным контекстом, для запроса информации или инициирования действия. Вот пример использования библиотеки Python requests:
import requests
response = requests.get('http://target-context/api/data')
  1. Асинхронный обмен сообщениями с помощью брокеров сообщений.
    Другим часто используемым методом является асинхронный обмен сообщениями с брокерами сообщений. Ограниченные контексты могут публиковать сообщения брокеру сообщений, а другие ограниченные контексты могут подписываться на эти сообщения и использовать их. Это отделяет отправителей от получателей. Вот пример использования RabbitMQ и библиотеки pikaв Python:
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='my_queue')
channel.basic_publish(exchange='', routing_key='my_queue', body='Hello, World!')
connection.close()
  1. Событийно-ориентированная архитектура с источником событий.
    Событийно-ориентированная архитектура в сочетании с источником событий — еще один мощный способ инициировать связь между ограниченными контекстами. В этом подходе ограниченные контексты излучают события всякий раз, когда происходит значительное действие или изменение состояния, а другие ограниченные контексты подписываются на эти события, чтобы реагировать соответствующим образом. Вот пример использования Axon Framework на Java:
@EventSourcingHandler
private void on(OrderPlacedEvent event) {
    // Handle the order placed event
}
public void placeOrder(String orderId) {
    // Place the order
    OrderPlacedEvent event = new OrderPlacedEvent(orderId);
    eventBus.publish(event);
}
  1. Удаленные вызовы процедур (RPC):
    RPC позволяет ограниченным контекстам вызывать методы или функции в удаленных службах, как если бы они были локальными. Этот метод часто используется, когда необходимо обеспечить тесную связь между вызывающим и вызываемым объектом. Вот пример использования gRPC и буферов протоколов в Go:
service MyService {
    rpc MyMethod(MyRequest) returns (MyResponse) {}
}
message MyRequest {
    string data = 1;
}
message MyResponse {
    string result = 1;
}
import (
    "context"
    "google.golang.org/grpc"
)
func main() {
    conn, err := grpc.Dial("target-context:50051", grpc.WithInsecure())
    if err != nil {
        log.Fatalf("Failed to connect: %v", err)
    }
    defer conn.Close()
    client := pb.NewMyServiceClient(conn)
    response, err := client.MyMethod(context.Background(), &pb.MyRequest{Data: "Hello"})
    if err != nil {
        log.Fatalf("RPC failed: %v", err)
    }
    fmt.Println(response.Result)
}

Это всего лишь несколько примеров того, как можно инициировать взаимодействие между ограниченными контекстами. Выбор метода зависит от конкретных требований и ограничений вашей системы. Используя комбинацию этих методов, вы можете создать гибкую и масштабируемую архитектуру для своих микросервисов.