Bargaining Struggling to find meaning Reaching out to others Telling one’s story Depression Overwhelmed Helplessness Hostility Flight Acceptance Exploring options New plan in place Moving on Kübler-Ross Model Five Stages of Grief
code before and/or after the endpoint has been processed. API Logging Instrumentation Log request, response and metadata Measure latency, count requests, etc.
code before and/or after the endpoint has been processed. API Logging Instrumentation Tracing Log request, response and metadata Measure latency, count requests, etc. Monitor code execution across services
code before and/or after the endpoint has been processed. API Logging Instrumentation Tracing Activity Recording Log request, response and metadata Measure latency, count requests, etc. Monitor code execution across services Record user activity for analytics
NewLoggingMiddleware(api, …) api = NewInstrumentingMiddleware(api, …) api = NewTracinggMiddleware(api, …) api = NewRecordingMiddleware(api, …) server.Serve(api) } All the middlewares
NewLoggingMiddleware(api, …) api = NewInstrumentingMiddleware(api, …) api = NewTracinggMiddleware(api, …) api = NewRecordingMiddleware(api, …) server.Serve(api) } All the middlewares
response fields change - New features result in new endpoints - Deprecated features result in endpoints getting deleted What that means for our project: - Every changes requires to update all files related to api.go - 4 Middlewares + Server Encoder/Decoder + Client Library = 6 Files
in the case of Go: generics - Delegate task to write boilerplate code to a machine - It’s mentally more satisfying to do meta-programming - Less prone to errors Model Tool Templates Code
generate which scans packages for generate directives and for each directive, the specified generator is run; if files are named, they must be Go source files and generation happens only for directives in those files, i.e. you would put this line at the top of your file: //go:generate echo ‘Hello Gophercon Russia’ $ go generate api.go > Hello Gophercon Russia
Invokes tool with file name as environment variable Templates Parse file(s) containing the directive Boilerplate Code Pass model to templates api/logging.go api/instrumentation.go api/recording.go api/tracing.go client/endpoints.go server/endpoints.go
tree for Go packages. Abstract Syntax Tree A tree representation of the abstract syntactic structure of source code written in a programming language. Each node of the tree denotes a construct occurring in the source code. - parser.ParseFile to create the AST by parsing an actual Go source file - ast.Inspect allows to iterate every node and extract further data
your templates for your colleagues to see - Intended to be used by the author of the Go package, not its clients - go:generate created code should be committed to the repository - Generate your unit tests, too - Make your code generation tool robust
is a meta tool that you can use as a building block to build your own tools: fitted for your purpose - Identity repetitive tasks in your development cycle and try to extract the essence into tooling - Make the tool part of your existing automation as well, i.e. run it in your CI/CD pipeline - Beware of breaking changes, it’s another tool in your stack, so it may require maintenance