
Storing program parameters in text configurations is a fairly frequent and seemingly trivial task. Many immediately grunted: what's the problem? There are a lot of formats (and libraries to work with them): properties, XML, JSON, YAML. In what you want - in that and keep it. Delov something.
However, the scale forced to look at it differently. In particular, after many years of developing Java game servers, I gradually came to the conclusion that managing configs is not so trivial. This article will focus on the HOCON format - what opportunities it provides and why in the last project we began to use them. More specifically, we use
Typesafe Config - opensource library written in Java.
HOCON is a config file format based on JSON. Compared to JSON, this format is less strict and has additional features:
')
{
However, the main value of HOCON is copying the values of variables and even whole JSON objects.
{ a: 42 b: ${a}
This, of course, is fun, the reader will say, but why do I need this? Why make a fuss all this garden instead of storing your configs in the usual JSON or XML? To answer this reasonable question, I will share two examples from our working practice.
Example 1. From the life of admins
We develop game servers. And game servers are a whole zoo of services which, depending on requirements, can work on a different set of hardware and in different layouts. As an example, I will give the layout of services by host from one of my past projects:

And all these services, of course, need to configure a whole bunch of parameters: here and all network addresses, and database names, users, accesses and God knows what else. The parameters of these are approximately 100,500.
Suppose, for example, we have three services s1, s2, s3, which need to configure an IP address:
{ s1 : { ip: “192.168.10.1” } s2 : { ip: “192.168.10.1” } s3 : { ip: “192.168.10.1” } }
Very often, these services run on the same host and have the same IP address. And we don’t want to climb around the configuration and change them everywhere when changing the IP address (remember that in life there are not three, but 100,500). What to do? If you store the config in the usual JSON, then you could get the host_ip common parameter and write something like this code:
ip = config.getValue(“s1.ip”); if ( ip == null ) { ip = config.getValue(“host_ip”); }
However, this solution has significant drawbacks:
- The developer of the service may not provide for this particular case.
- This logic is hidden from the administrator who configures configs. How does he know that if the parameter s1.ip is not specified, then it will be taken from the parameter host_ip? If there are a lot of parameters and they will often make such tricks, then a heart attack can happen to the administrator (and his shadow will be the developer at night).
At HOCON, the solution is completely transparent:
{ host_ip: “192.168.10.1” s1 : { ip: ${host_ip} } s2 : { ip: ${host_ip} } s3 : { ip: ${host_ip} } }
Example 2. From the life of developers
When developing the task of deploying a new server from scratch does not arise so rarely. Brought a new branch. Hired a new programmer. Flew old hard drive, and we must all put again. Since the local server is also a full-fledged zoo with all services (albeit one by one), then, of course, I don’t want to configure the config from scratch every time. This suggests an option to store the common config in the version control system along with the code, and when you sweep the local server, change only the host IP in it. Well, let's use the solution from the last example:
{ host_ip: “192.168.10.1” s1 : { ip: ${host_ip} } s2 : { ip: ${host_ip} } s3 : { ip: ${host_ip} } }
But here there is a snag: the general config lies under the version control system! If I change the host_ip in it, then there will be a lot of inconvenience: the diff is constantly hanging, we must merge the changes made by others. God forbid you accidentally commit your host_ip to a common version. You can also store a common config somewhere else and put it in the right place. But how then will there be changes made in the version by other developers?
And here we come to the rescue of the include directive:
{ host_ip: “127.0.0.1”
And next to the main config file, we enclose the local_config.conf file with the following contents:
{ host_ip: “192.168.10.1”
The local_config.conf file is ignored by the version control system, no conflicts occur.
Conclusion
Considered examples of use are taken from real development. And of course, the possibilities of HOCON are not limited to them. In fact, HOCON is not just a text format, but rather a highly specialized script for configs, which can make life easier for the administrator and developers.
I did not specifically mention here a more detailed description: everything is beautifully stated in the
official manual . If you have your noteworthy cases of using this library - share them in the comments!