Microservices And Messaging · How to use it
1 min readHow to use it
Conceptually, two everyday tasks for a backend developer:
Adding an endpoint to a service
the persistence in Infrastructure (EF Core), and only the HTTP plumbing in API.
Response DTO, the route in Configure(), and HandleAsync. Remember the route is relative to the global api/v1 prefix.
service's own realm (the realm wall does this for you). Only add AllowAnonymous() if the route is genuinely public (e.g. a public viewer page).
by hand inside the handler.
filter already scopes them to the current tenant; don't write manual TenantId filters and don't bypass the filter without a very good reason.
- Pick the layer. Put the use-case logic in Application (a handler),
- Create a FastEndpoints class in the API layer: a
RequestDTO, a - Decide on auth. By default the endpoint requires a valid token from the
- Add a validator (
Validator<TRequest>) for input rules — don't validate - Stay tenant-safe. If you query tenant-owned entities, the global query
Publishing (or consuming) an event
publisher and any consumer reference the exact same type. Keep it small and versionable — other services depend on its shape.
and calling Publish(...). Do this after your local work succeeds; don't block waiting for consumers.
IConsumer<TEvent>; the shared Messaging.RabbitMq wiring discovers and registers it on the bus.
subscription status), prefer a guarded internal HTTP call with a shared secret and a cached fail-safe instead of an event.
- Define the contract as a record in
Messaging.Contractsso both the - Publish from your handler by injecting MassTransit's
IPublishEndpoint - Consume (in the interested service) by implementing
- Ask, don't tell? If you actually need an answer before continuing (like