Layers
Don't mix business logic with service logic
February 21, 2017Go kit has a pretty opinionated view about how a Go-based micro-service should work:
- You start with core business logic
- Then wrap it in flexible layers adding
- Handlers
- Endpoints
- Transports
Though it seems tedious at first, I found myself feeling a certain clarity while working on a small experiment in it. The stringsvc shows the flow from logic through the layers, and though a trivial example, it shows off the disciplines needed to keep sane when working on webapps:
- It starts with an interface for the service (public, verbs in the typically simple Go form)
- And an implementation (a private struct, same name as the interface)
- Define request and response formats (
json:
annotations in this case) Endpoint
construction is a closure over the service layer- The
Endpoint
format stays clean(context, interface{}) -> (interface{}, err)
- Transports are built on top of endpoints
This all sounds daunting but it serves some benefits straight away. Domains can be filled in at the service layer and the closure over the service makes for less passing around.
Note: I didn't say anything about having to set up middleware for logging and other traceability factors. The patterns for this also show some thought. They're compositional wrappers that take and return an Endpoint
, making them pretty easy to reason about.