Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [config-dev] More Thoughts on Application Developer Use Cases

Thanks for sharing all this. I look forward to seeing API proposals.

So far, are we thinking the MicroProfile approach needs to be significantly improved upon or is it mostly OK? We should also probably consider the fact that CDI producers have some level of overlap with how Spring thinks about configurations is general.

Reza Rahman
Jakarta EE Ambassador, Author, Blogger, Speaker

Please note views expressed here are my own as an individual community member and do not reflect the views of my employer.

From: config-dev <config-dev-bounces@xxxxxxxxxxx> on behalf of Laird Nelson <ljnelson@xxxxxxxxx>
Sent: Tuesday, October 12, 2021 12:43 PM
To: Jakarta Config project developer discussions
Subject: [config-dev] More Thoughts on Application Developer Use Cases
Dmitry encouraged more activity on the mailing list so here is more activity on the mailing list

I've previously brought up the topic of application developer use cases:

I've also previously talked about the different shapes of configuration objects in the world:

How do other configuration subsystems deal with all this?  Here's an arbitrary survey of sorts.

Spring understands all this very well: you, the application developer, designate an object as a configuration object and Spring hands it to you.  The configuration object is designed by the application developer.  While it is not exactly required to, it usually bears Spring-defined annotations on it, lightly coupling this developer-defined object to Spring.  (Spring also lets you, if you wish, designate the method that makes your configuration object, which may lean on other Spring facilities to make it.)

This is an example of a configuration "frontend", which I'll define below—loosely, what hoops the application developer has to jump through to get her object—with a "backend", which I'll also define below—loosely, what makes the thing the "frontend" serves up—nicely hidden from view.  It leaks the backend (annotations) but is basically pretty clean.

MicroProfile Config has two "frontend" models, one built on top of the other.  Model 1 is: there is exactly one kind of configuration object: org.eclipse.microprofile.config.Config.  It is a key/value prober with no guarantees about what values it might contain at any given point in time or what types any given arbitrary String-typed value it might contain can validly be converted to.  The developer can acquire it with a simple bootstrappy acquisition method and start probing to see what it holds at the time that she starts probing it.

Built atop this in version 2.0 is the Spring-like "configuration properties" model (Model 2), where the application developer designs an interface and annotates it with some MicroProfile Config annotations that help the "backend" implement it.  If the developer is using CDI, she can inject her configuration properties object which the "backend" has magically implemented in terms of Model 1 for her (like Spring does with its configuration properties model).

Model 1 leaks (mostly harmlessly and occasionally usefully) the "backend" by exposing the ConfigSources that make up the Config.  Model 2 is built under the covers in terms of Model 1 and tries to hide the "backend", but lets it leak through (annotations) in much the same way that Spring does.  Like Spring's configuration "frontend", it's also pretty good.

DropWizard says: in order to create an application, you first have to indicate what kind of configuration object you're expecting (design the interface or class).  Then DropWizard arranges for that object to be handed to you on startup without requiring any other injection mechanism.  The configuration object is designed by the application developer.

This is a very clean "frontend" example where "the backend" can be completely hidden.  DropWizard gets away with this because there is exactly one backend (Jackson) and it is strongly opinionated and doesn't require annotations (see its concept of mixins).  There's no coupling of your configuration object to the backend at all.

(As a limiting case just to further flesh out these concepts: the JDK itself has a "frontend" with two possible configuration objects (a map of environment variables and a map of system properties).  The developer acquires either via a simple acquisition method on a bootstrappy "frontend" API (java.lang.System) and starts probing.  The "backends" in this case (the machinery that finds and pumps environment variables into the Java process, the Java mechanism that gets system properties and tunnels them into System itself) are hidden.)

So then: in these examples, by "frontend" I mean (1) the thing the application developer designs and consumes and (2) the ceremony she has to perform to get it.  It's the configuration object and the way that the developer acquires it.  The frontend use cases don't involve the backend at all.

And by the "backend" I mean the actual configuration harvester that "makes" or binds or fills or composites the thing being consumed in the frontend out of configuration data.  The backend use cases don't involve the frontend except, obviously, in that they result in a configuration object used by the frontend.

As you can see, there are similar patterns in all of these frameworks when it comes to an application developer acquiring the configuration object she wants to use.  They're all subtly different, too.

I like thinking about all of them in terms of backends that make things without knowing how they'll be acquired and frontends that acquire made things without knowing how they're made.  Very DI-ish but without the complexity because there's very little "I". I'll stop here for the time being and just let all this percolate.


Back to the top