Informative article elithrar - thanks!. Wondering why appContext was used instead of goji's Context/environment object ?
Does not a context struct that holds all the handler dependencies makes the code harder to ponder and test(because the dependencies of a component would be unclear).
Wondering whether testing/debugging would be a little less complex if we create separate handler-groups/components? That would make the main() very verbose with all the wiring - (one of the things the inject lib tries to solve).
From what i understand there seems to be two line of thoughts.
#1) Being verbose is good - Components whose constructors take all of their dependencies are simple to reason about and straightforward to test
#2) When there are several binaries that share libraries - allocating memory, and wiring up the object graph becomes mundane and repetitive. Solving this by using a DI library like inject that doesn't add run-time overhead would be good. This doesn't have to happen at the cost of being difficult to test/reason-out.
> Informative article elithrar - thanks!. Wondering why appContext was used instead of goji's Context/environment object ? Does not a context struct that holds all the handler dependencies makes the code harder to ponder and test (because the dependencies of a component would be unclear).
Goji's context is a request context, and only exists for the lifetime of the request. Re-populating it at the beginning of every request would be a significant amount of overhead, and it's ultimately not designed for "life-of-application" variables. Request contexts like Goji's (or gorilla/context) are best used for passing short-lived data between middleware/handlers.
You could ultimately create a series of smaller structs, but you would need a ton of types (and repetitive code) that satisfy http.Handler to achieve that.
Memory allocation with this approach is minimal: you're only passing a struct pointer around once per request, which is about as good as it gets (better than a closure).
Testing with this approach is also straightforward: you can populate the appContext instance with your test sessions|database|etc when running tests, and your handlers operate as if they've been passed the real thing.
I've considered splitting out my handlers into a `handlers` package and the appContext struct/config structs into a `conf` package that handlers imports (and main initialises), and that's probably something I'll do in the near future since it's an easy change.
It's certainly not the one way/single best way to do things, but I've found that aligning to interfaces (like http.Handler) and leaning on structs as much as possible helps keeps things easier to reason and mock out later.
Wondering whether testing/debugging would be a little less complex if we create separate handler-groups/components? That would make the main() very verbose with all the wiring - (one of the things the inject lib tries to solve).
From what i understand there seems to be two line of thoughts.
#1) Being verbose is good - Components whose constructors take all of their dependencies are simple to reason about and straightforward to test
#2) When there are several binaries that share libraries - allocating memory, and wiring up the object graph becomes mundane and repetitive. Solving this by using a DI library like inject that doesn't add run-time overhead would be good. This doesn't have to happen at the cost of being difficult to test/reason-out.
Guess each might have it's own place.