Adding Properties to Restful Service, Part II

Last time, we looked at adding properties to an application with Spring Boot. Besides injecting simple properties, it provides additional, more powerful options for working with properties.

Properties Objects

Spring allows you to use the @ConfigurationProperties annotation to define an object bound to a subset of the properties in your properties file.

@ConfigurationProperties(name="service")
public class ServiceProperties {
    private String message;
    private int value = 0;
    ... getters and setters
}

In this example, a ServiceProperties object will have its values bound to the properties “service.message” and “service.value” from the properties file. Note the @ConfigurationProperties name attribute is the prefix for the property in the properties file (“service”), and the bean properties in the object (“message” and “value”) are the name of the rest of the property in the properties file. It’s a very consistent system and is an easy way to get lots of validated and parsed properties into your system.

Is There A Downside?

I like the concept but think there are some liabilities with this approach.

It should be easy to look at a properties file and tell where the properties are used, and it should be easy to look at code and tell where the properties values are defined. I call this bidirectional discoverability, and it’s very important concept (not just for properties) as a system gets very large. Using @Value and @Inject to get properties into your code allows you to grep for a property name and always discover both the definition and the usage because the entire string is exactly the same.

Additionally this approach adds to the number of classes in your system. Generally less code means less room for error and easier comprehension of your codebase.

Finally, the properties object requires setters to set the properties. This means that every time you use a properties object, mutation of properties by the caller is a possibility. This is a disadvantage because usually configuration properties in an application are immutable.

Is There An Upside?

On the other hand, a reason for using @ConfigurationProperties would be if you had a large set of properties (say, more than 4 or 5) that logically made sense to stay together. The properties class more strongly implies that they are intended to be used together, aiding developer comprehension if a property needs to be used elsewhere. This also reduces the number of constructor arguments for the class using the properties, because we can inject a single configuration object instead of 4, 5, or more @Value objects.

Mitigation

Given the caveats, there should be a compelling reason to add this properties class over simple property injection. But if you find the benefits outweighing the costs, there are ways to work around the downsides.

We could use @ConfigurationProperties and make it our convention that each attribute be commented with the entire property name to enable bidirectional search.

Additionally we can make the properties object immutable by having the properties object implement a getter interface, declare the properties object as a @Component, and @Inject the the getter interface instead of the actual properties object. This would reduce the possibility of accidentally mutating the properties.

Advertisements

Leave a comment

Filed under Software Engineering

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s