Skip to content

Overview

Handlers are declared like routes, and guards, interceptors, pipes and filters run on them with ExecutionContext.Kind() == dygo.KindRPC:

func (h *UsersHandlers) Patterns(r micro.Router) {
r = r.Use(dygo.Guards(dygo.Ref[*ServiceTokenGuard]()))
r.Message("users.get", micro.Handle(h.get)) // request/response
r.Event("orders.created", micro.HandleEvent(h.onOrder)) // fire and forget, any number of handlers
}

Serve them over NATS in the same process as HTTP (a hybrid app):

app, _ := dygo.Create(ctx, AppModule())
app.ConnectMicroservice(nats.NewServer(nats.Options{URL: nats.DefaultURL, Queue: "users"}))
app.Listen(ctx, ":9900") // starts NATS too; shutdown closes both

Call other services with a *micro.Client (nats.ClientModule(nats.ClientOptions{URL: ...}) provides one):

u, err := micro.Send[*User](ctx, client, "users.get", GetUser{ID: id})
err = client.Emit(ctx, "orders.created", OrderCreated{ID: id})

A handler’s *errs.HTTPError arrives at the caller as the same *errs.HTTPError, so a gateway route passes a 404 on unchanged. micro.WithHeader(ctx, k, v) and the client’s micro.Before hook set headers; handlers read them with micro.MessageFrom(ctx). In tests, micro.NewLocal is both the transport and the client, with no broker.

Transports run only their own global enhancers (ServerOptions.Global). Set InheritAppConfig to also run the app’s global ones; they must then handle hosts where HTTP() is nil.

The same handlers run over Redis pub/sub or Kafka; only the server and client change:

app.ConnectMicroservice(redis.NewServer(redis.Options{Addr: "localhost:6379"}))
redis.ClientModule(redis.ClientOptions{Redis: goredis.Options{Addr: "localhost:6379"}}) // provides *micro.Client
app.ConnectMicroservice(kafka.NewServer(kafka.Options{Brokers: []string{"localhost:9092"}, GroupID: "users"}))
kafka.ClientModule(kafka.ClientOptions{Brokers: []string{"localhost:9092"}})

Redis patterns with *, ? or [ are glob subscriptions (orders.*). Redis pub/sub keeps nothing: an event with no server running is lost, and a request with no server fails at once with micro.ErrNoHandler. Kafka patterns starting with ^ are regexps over topic names (^orders\..*); every server in one GroupID shares the partitions, and each client gets its own reply topic, deleted when it closes.