5 ms·
We use strongly typed contexts for: - Request-scoped parameters like user ID, request ID, etc. - Dependency injection (database connection and other IO) - Ca
by et1337 3y ago
We use strongly typed contexts for:
- Request-scoped parameters like user ID, request ID, etc.
- Dependency injection (database connection and other IO)
- Cancellation
It works great. The one hairy part is when you need to change the context, for example when logging in you take an anonymous context and end up with a logged-in context. We use linters to ensure that stuff is right, but it still takes some thought in the edge cases.
Still, I think those issues are exposing problems in our codebase rather than problems with typed contexts.
- rcme 3y agoWhy do you use it for dependency injection? Why can you not pass those parameters directly when instantiating your service?
- et1337 3y agoBecause there’s a lot of them. Logging, MQ messages, database connection, emails, S3. If we want to limit which of these are available to the code, we do so using a strongly typed context. (For example a ReadOnlyContext) The only use of dependency injection for us is testing. Our test fixtures have to provide both request-scoped info (user ID etc.) and mocks for IO. It makes sense to do that all in one object.
- candiddevmike 3y agoDo you use a single context key with a struct or iota keys for each value?
- et1337 3y agoI experimented with the struct because I was too lazy to do the iota keys. It works but it can be a foot gun. We have multiple strongly typed contexts (again one example would be anonymous vs logged in context) and with the struct approach, it’s easy to get in a situation where you lose one of your values by passing the context through a layer that doesn’t know about your types. I still think these gotchas are indicative of issues in the codebase rather than the struct or the typed context. They only come up in the hairiest parts of the code.