Write a Transport Block
Host / Resolver / RouteServiceBinder
A transport block connects a request protocol, such as HTTP, WebSocket, JSON-RPC, or future gRPC. It is not part of the kernel. It connects to the application through Provider and Host.
What a transport block is responsible for
A transport block usually needs:
- Its own Server or Registry.
Provider()to register DI and Host.- Optional commands.
- Optional
Resolvestage for delayed mounts. Shutdownor Host Stop to release resources.
Start with the minimum shape
type Server struct {}
func New() *Server { return &Server{} }
func Provider(server *Server) provider.Provider {
return providerImpl{server: server}
}
type providerImpl struct {
provider.Base
server *Server
}
func (providerImpl) Name() string { return "custom" }
func (p providerImpl) Init(_ context.Context, ctx provider.Context) error {
provider.ProvideValueOnce(ctx, p.server)
return nil
}
func (p providerImpl) Register(ctx provider.Context) error {
return ctx.RegisterHost(NewHost(p.server))
}
Long-running services must use Host
Host implements:
type Unit interface {
Name() string
Start(context.Context) error
Stop(context.Context) error
Status() host.Status
}
Long-running transport services should use Host instead of starting goroutines directly inside Provider.
Integrate with route only when HTTP is needed
If the transport block runs on HTTP, such as JSON-RPC or WebSocket, it can read *route.Registry during Register and mount itself:
routes := provider.MustInvoke[*route.Registry](ctx)
Mount(routes.RouteGroup(), server)
This kind of transport should explicitly depend on route, while the kernel still does not depend on it.
Acceptance checklist
- It does not import
runtime. - It can be used standalone through
New(). - Provider can register a Host or mount into route.
- Shutdown or Stop releases resources.
- Documentation explains install path, Provider example, and config.