GO KIT vs Mux vs net/http
GoKit
GoKit is more of do it urself thing where they define the flow and leave it to us to define the functions
https://github.com/go-kit/kit/blob/master/transport/http/client.go#L90
https://github.com/go-kit/kit/blob/master/transport/http/server.go#L95
Server Side & Client Side
Sever Side
In server side for each endpoint we can write
- ServerBeforefns
- typically used for getting request headers, token data etc and putting into context
- Decode fn
- request json to struct conversion
- Enpoint fn
- calls the service implementation
- ServerAfter fn
- for any cleanup work
- Encode fn
- response struct to json
Error Handling
Anypoint if there is an error, we can also use an Error handler to handle the error. Basically do something like REST http code to service error code mapping. Its left upto us on how to define this
Client Side
- Client gets inputs and makes a struct
- Which is encoded into json and sent as payload in req
- Similar to server side here also we have ClientBefore and ClientAfter fns
Plugging Middlewares
Since this only recommends a certain format of fns, and all of these fns actually take in a request and give a response.. they say we can plugin any sort of transport (http, grpc etc)... Havent explored to this level but the go-kit github has examples
Also it is very easy to chain endpoint fn - mainly used for plugging middlewares like logging
typeloggingMiddlewarestruct {
next Service
logger log.Logger
}
func NewLoggingMiddleware(logger log.Logger) Middleware {
returnfunc(next Service) Service {
return &loggingMiddleware{
next: next,
logger: logger,
}
}
}
func (mw loggingMiddleware) PostPackage(ctx context.Context, packageOptions *PackageRequestMeta, valuesFile *fileUtils.InputFile, archiveFile *fileUtils.InputFile) (application *v1alpha1.Application, err error) {
deferfunc(begin time.Time) {
mw.logger.Log("method", "PostPackage", "took", time.Since(begin), "err", err)
}(time.Now())
return mw.next.PostPackage(ctx, packageOptions, valuesFile, archiveFile)
}
// the NewLoggingMiddleware fn is like a higher order fn
// I can pass any service to it ..
deployService = deploy.New(conf, logger)
deployService = deploy.NewLoggingMiddleware(logger)(deployService)
It takes a while to get used to this but its very powerful.. I often get confused with all the abstractions and have to lookup stuff.
In postPackage fn, it registers a deferred fn with parameter time.Now for begin then it calls the actual service implementation PostPackage. Once its executed and control returns here, it will log the execution time
Constraints
Its hard to understand go/kit unless you run both client and server in debug mode in vscode and trace the steps
References
- Getting started with Go kit - Márk Sági-Kazár (sagikazarmark.hu)
- https://github.com/go-kit/kit/blob/master/transport/http/client.go#L90
- https://github.com/go-kit/kit/blob/master/transport/http/server.go#L95
Appendix
There are also ServerFinalizer and ClientFinalizer functions but I havent used them much