The code generator is Microbus
’s most powerful productivity tool. It takes as input definitions from service.yaml
to produce boilerplate and skeleton code that saves valuable engineering time to do more meaningful work. Boilerplate code is generally tucked away in *-gen.go
files and used to add type safety to the individual microservice or to automate repetitive code. Skeleton code, on the other hand, is a placeholder marked with TODO
s that prompts the engineer to fill in meaningful code.
Skeletons of the OnStartup
and OnShutDown
lifecycle callbacks are created for all microservice.
// OnStartup is called when the microservice is started up.
func (svc *Service) OnStartup(ctx context.Context) (err error) {
// TO DO: Implement OnStartup
return nil
}
// OnShutdown is called when the microservice is shut down.
func (svc *Service) OnShutdown(ctx context.Context) (err error) {
// TO DO: Implement OnShutdown
return nil
}
These callbacks are registered with the Connector
in the internal NewService
method in intermediate-gen.go
.
When a web endpoint is defined in service.yaml
, the code generator creates the following skeleton in service.go
:
/*
WebHandler is an example of a web handler.
*/
func (svc *Service) WebHandler(w http.ResponseWriter, r *http.Request) (err error) {
// TO DO: Implement WebHandler
// ctx := r.Context()
return nil
}
This web handler is also registered with the Connector
in intermediate-gen.go
.
For functional endpoints and event sinks, the code generator creates a type-safe skeleton that matches the definition in service.yaml
, always adding a ctx context.Context
input argument and an err error
return value.
/*
FuncHandler is an example of a functional handler.
*/
func (svc *Service) FuncHandler(ctx context.Context, id string) (ok bool, err error) {
// TO DO: Implement FuncHandler
return ok, nil
}
Behind the scenes, a web handler is created that performs unmarshaling of the request and marshaling of the response to match the arguments of the function. It is this web handler that is registered with the Connector
.
Skeletons of tickers have a simple signature. They too are registered with the Connector
in intermediate-gen.go
.
/*
RecurringJob is an example of a ticker handler.
*/
func (svc *Service) RecurringJob(ctx context.Context) (err error) {
// TO DO: Implement RecurringJob
return nil
}
If a config designates a callback, it will be created with the following signature:
// OnChangedMyConfig is triggered when the value of the MyConfig config property changes.
func (svc *Service) OnChangedMyConfig(ctx context.Context) (err error) {
// TO DO: Implement OnChangedMyConfig
// val := svc.MyConfig()
return nil
}
A skeleton test is created in integration_test.go
for each testable web handler, functional endpoint, event, event sink and config callback. For example:
func TestMyService_FuncHandler(t *testing.T) {
t.Parallel()
/*
FuncHandler(t, ctx, id).
Expect(ok).
NoError()
*/
ctx := Context()
// TO DO: Test FuncHandler
}