Skip to content

gRPC Client

pkg/grpc/client establishes a gRPC connection and registers a typed client in DI via WithClient.

Pass WithClient a proto-generated constructor (func(*grpc.ClientConn) T). The typed client is registered directly in DI — no need to ever handle the raw connection.

lakta.NewRuntime(
config.NewModule(
config.WithConfigDirs(".", "./config"),
config.WithArgs(os.Args[1:]),
),
tint.NewModule(),
slog.NewModule(),
otel.NewModule(),
grpcclient.NewModule(
grpcclient.WithName("data"),
grpcclient.WithClient(v1.NewDataServiceClient),
),
grpcclient.NewModule(
grpcclient.WithName("orchestrator"),
grpcclient.WithClient(v1.NewWorkflowServiceClient),
),
myapp.NewModule(),
)

Use lakta.Invoke[T](ctx) in any handler. The typed interface is what was registered — not the raw *grpc.ClientConn.

// gRPC handler
func (s *MyServer) PlaceOrder(ctx context.Context, req *pb.PlaceOrderRequest) (*pb.PlaceOrderResponse, error) {
dataClient, err := lakta.Invoke[v1.DataServiceClient](ctx)
if err != nil {
return nil, err
}
return dataClient.CreateOrder(ctx, &v1.CreateOrderRequest{...})
}
// HTTP handler (Fiber)
func handlePost(c fiber.Ctx) error {
client, err := lakta.Invoke[v1.DataServiceClient](c.Context())
if err != nil {
return err
}
resp, err := client.GetThing(c.Context(), &v1.GetThingRequest{Id: c.Params("id")})
...
}

Each instance needs a name and its own config block:

grpcclient.NewModule(
grpcclient.WithName("data"),
grpcclient.WithClient(v1.NewDataServiceClient),
),
grpcclient.NewModule(
grpcclient.WithName("orchestrator"),
grpcclient.WithClient(v1.NewWorkflowServiceClient),
),
modules:
grpc:
client:
data:
target: "data-svc:50051"
insecure: true
orchestrator:
target: "orchestrator-svc:50052"
insecure: true

See Multi-instance Modules for the full pattern.

Config path: modules.grpc.client.<name>

target string default: localhost:50051

target specifies the target address for the gRPC client connection

env LAKTA_MODULES_GRPC_CLIENT_<NAME>_TARGET
insecure bool

insecure determines whether transport credentials should use an insecure configuration

env LAKTA_MODULES_GRPC_CLIENT_<NAME>_INSECURE

These options can only be set in Go code via With*() functions, not via config files or environment variables.

OptionTypeDescription
Credentials(...)credentials.TransportCredentials
WithClient(...)[]client.ClientRegistrarregisters a typed client constructor (code-only)