Best practices for Dagger on the server-side?

257 views
Skip to first unread message

Gregg Donovan

unread,
Mar 6, 2019, 4:24:00 PM3/6/19
to Dagger Discuss
Hello! We (Etsy) are interested in adopting Dagger for server-side applications. We'd like to use dependency injection, but without the downsides of reflection and proxies. We're also Bazel users, so it's reassuring to know that combination is well-exercised.

I'm wondering if folks who are using Dagger on the server-side might pass along some ideas and best-practices for doing so. The documentation in this area is a little light, so any pointers would be helpful. A few areas of specific interest:

End-to-End Examples: So far the best OSS example I can find of server-side Dagger is Google Nomulus. Are there others that are worth looking at?

Lifecycle management: For example, some of our services need to read in large files, connect to databases or caching services, etc. on startup before they're ready to serve traffic. Spring and Micronaut handle this via the PostConstruct annotation, but Ron Shapiro had suggested using method injection to achieve the same thing. Is that still the best advice?

Static Configuration: We'd like to be able to inject static configuration -- system properties, environment variables, and config files. In Nomulus, a POJO is created representing a large set of configuration (example) and the @Provides methods (example) and qualifiers (example) make subsets of this configuration available for injection. Is this good practice? Is there anything better? It's a bit more verbose to setup than @Value from Spring/Micronaut, but I like having the config consolidated and well typed.

Dynamic Configuration: We also have dynamic configuration variables that we would like to inject. These can change during our service's lifetime. For example, a list of database replicas might change when databases get replaced or scaled up. But we don't want to go to a config service on each reference to the list of databases -- after the data changes, it should be locally available. The interface I think we'd want for this is something like Supplier<T> with T being the type of configuration data. Any ideas or examples? The Spring/Micronaut solution of @RefreshableScope seems to makes the dynamic nature of the data somewhat opaque to the callee.


Thanks in advance!

Gregg


Ron Shapiro

unread,
Mar 6, 2019, 5:15:23 PM3/6/19
to dagger-...@googlegroups.com
Assorted thoughts:

Are you aware of dagger.grpc? That could be helpful.

Re: Lifecycle: Can you make bindings out of those objects? That would be the most ideal. Otherwise that linked issue is probably our best recommendation.

Re: Static Configuration, that's in line with the best practices we've seen.

Re: dynamic configuration: there are some servers that accomplish this by having something like a refreshable scope. Whenever one of the components that is refering to an out of date database, you can toss away that component, create a new instance and then move on from there. That also helps to make sure that no on is leaking that instance via the Supplier (though still possible, but less likely).

We have future dreams of having a JVM web application framework that is powered by Dagger. We don't have the resources to do that now, but if you're writing something and you happen to make it reusable, we could try to review+help with that.

--
You received this message because you are subscribed to the Google Groups "Dagger Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dagger-discus...@googlegroups.com.
To post to this group, send email to dagger-...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Gregg Donovan

unread,
Mar 6, 2019, 6:40:04 PM3/6/19
to Dagger Discuss
Ron,

Thank you so much -- this is really helpful. 


On Wednesday, March 6, 2019 at 5:15:23 PM UTC-5, Ron Shapiro wrote:
Assorted thoughts:

Are you aware of dagger.grpc? That could be helpful.

We're just getting started on migrating from Thrift to gRPC, so these could come in handy later on.  

Re: Lifecycle: Can you make bindings out of those objects? That would be the most ideal. Otherwise that linked issue is probably our best recommendation.

Do you mean something like:

@Singleton
@Provides
static MyCache provideMyPrefilledCache() {
  return MyCache.prefilledInstance();
}
...
@Singleton
public class MyService {
  @Inject
  private MyCache myCache;
...



Re: Static Configuration, that's in line with the best practices we've seen.

Re: dynamic configuration: there are some servers that accomplish this by having something like a refreshable scope. Whenever one of the components that is refering to an out of date database, you can toss away that component, create a new instance and then move on from there. That also helps to make sure that no on is leaking that instance via the Supplier (though still possible, but less likely).

That sounds great. Do you have any examples of custom scopes out in the wild that might be a good guide? 


We have future dreams of having a JVM web application framework that is powered by Dagger. We don't have the resources to do that now, but if you're writing something and you happen to make it reusable, we could try to review+help with that.

Thanks for the offer! We're mainly writing backend services without any real web-frontend, but hopefully we can come up with some useful shared components, examples, or docs along the way.
Reply all
Reply to author
Forward
0 new messages