interface |- cmd/ |- <service-name> |- main.go <--- main package, executable of the Microservice |- store/ |- storer.go <--- definition of the storage interface |- postgres/ |- storage.go <--- implementation of the PostgreSQL storage |- migrations/ <--- SQL files the migration tool to setup the database scheme |- memory/ | storage.go <--- in-memory implementation, can be useful for testing the service without a DB |- provider/ <--- integration with external services, e.g. sms providers, etc. |- deploy/ |- deploy.yml <--- ansible deployment script |- config.ini.dist <--- configuration file template |- Makefile <--- instructions to setup the environment for a service, compile and install it
// server with pre-configured interceptors. // Set maxMsgSize to overwrite the default value in MiB, // Additional interceptors may be passed. func DefaultGRPCServer(maxMsgSize int, extra ...grpc.UnaryServerInterceptor) *grpc.Server { // Set sisu log as GRPC internal logger sdtLogger := sisulog.NewStdLogger() grpclog.SetLogger(sdtLogger) interceptors := []grpc.UnaryServerInterceptor{ NewRecoverPanicUnaryInterceptor(), NewRequestTracingUnaryInterceptor(), grpc_prometheus.UnaryServerInterceptor, } interceptors = append(interceptors, extra...) return grpc.NewServer( grpc_middleware.WithUnaryServerChain(interceptors...), grpc.MaxMsgSize(maxMsgSize), ) }
storage type Storer interface { // Get retrieves an address from a storage Get(ctx context.Context, id string) (*addresspb.Address, error) // Create adds an address to a storage Create(ctx context.Context, addr *addresspb.Address) error // Get removes an address from a storage Delete(ctx context.Context, id string) error }
based on database schema ◦ easy to use command line tool ◦ custom templates for additional functionalities (e.g. pagination) ◦ xo pgsql://user:pass@host/dbname -o models • more complex queries created manually 8
context to pass by trace_id and auth_user_id • outputs the messages in easy to parse and search format • logs errors to rollbar Example: url := "http://google.com" err := errors.New("terrible error") sisulog.Info(ctx, "Test log message", "url", url, "error", err) Test log message url=http://google.de error="terrible error" trace_id=123 auth_user_id=123 10
package • context aware • WrapErr() - ensures no error of the lower layers is lost and a call trace is created for the error path • UnwrapErr() - returns unwrapped error, used when leaving the application 11
functions to setup commonly used parameters • pgdb - used to establish a connection to a PostgreSQL DB and manage the PostgreSQL configuration • sisuio - used to close I/O streams that can return an error; logs an error if Close() fails • … 13