HOCON : une alternative élégante à JSON et YAML

Dans tout projet logiciel ayant un minimum d’envergure, la gestion de la configuration est un besoin récurrent. Il s’agit de permettre à l’utilisateur d’altérer le comportement d’un logiciel sans modifier celui-ci, car cela nécessiterait des compétences spécifiques ainsi que, le plus souvent, une recompilation rédhibitoire voire impossible.

Un levier de la configuration se joue grâce à la présence de fichiers textuels. L’utilisateur édite ces fichiers, exécute le logiciel, et hop! Celui-ci se comporte en fonction des paramètres décrits. Plusieurs formats ont traditionnellement été utilisés pour de tels fichiers. Sous Windows (puis Unix), les fichiers INI ont longtemps dominé. Depuis quelques temps, on préfère des formats comme JSON ou YAML, car ils permettent une structuration plus riche de l’information.

HOCON (pour Human-Optimized Config Object Notation) est un autre format typiquement utilisé pour la configuration. Il s’agit d’un super-ensemble de JSON: un document formaté en JSON est un document HOCON valide. Il permet cependant de faire « plus » ou « mieux »: sa syntaxe est plus permissive, au bénéfice d’un utilisateur humain qui peut (supposément) la lire et l’écrire plus facilement. En contrepartie, le format HOCON est notoirement plus difficile à parser pour un système informatique.

Principales différences par rapport à JSON

Parmi les différences avec JSON, notons tout d’abord la possibilité d’utiliser des commentaires.

// un commentaire
x: 123

Pour les chaînes de caractères, les guillemets peuvent être omis si l’interprétation n’est pas ambiguë. De même, la virgule en tant que séparateur est optionnelle si un retour à la ligne est utilisé.

user: {
  firstName: Mathieu
  lastName: Goeminne
}

Équivalent en JSON:

{
  "user": {
    "firstName": "Mathieu",
    "lastName": "Goeminne"
  }
}

Toujours concernant les chaînes de caractères, celles-ci peuvent s’étendre sur plusieurs lignes. Pratique lorsqu’on doit supporter des pavés textuels, ou tout simplement du texte pour lequel le retour à la ligne est important.

pi = """
   Que j’aime à faire apprendre un nombre utile aux sages !
   Immortel Archimède, artiste ingénieur,
   Qui de ton jugement peut priser la valeur ?
   Pour moi, ton problème eut de pareils avantages. 
"""

Différences supplémentaires, par rapport à YAML

Le format YAML a été créé pour éviter certaines des limitations de JSON en tant que format de configuration. HOCON présente cependant une approche alternative, supposément plus simple pour un utilisateur humain.

Une première différence d’importance entre YAML et HOCON est qu’HOCON ne repose pas sur une indentation particulière, souvent considérée comme une source de fragilité pour YAML:

app = {
  name = "MyApp"
  port = 8080
}

Équivalent en YAML:

app:
  name: "MyApp"
  port: 8080

Notez au passage que la présence d’accolades pour structurer la configuration permet une certaine analogie avec la différence entre d’une part la syntaxe des langages de programmation issus de C et d’autre part celle de Python. Notez également, qu’en HOCON, le symbole permettant l’association entre une clef et une valeur peut indifféremment être le caractère « = » ou « : ». Cela rapproche HOCON de l’affectation de variables telle qu’elle est gérée dans de nombreux langages de programmation.

Lorsque la valeur d’une affectation est un bloc, le symbole d’affectation peut être omis, ce qui renforce la concision de la syntaxe. Outre cette concision, cela facilite l’insertion de blocs de configuration déjà définis au sein d’une autre partie de la configuration: la réutilisation des (parties de) configurations s’en trouve facilitée.

app {
  name = "MyApp"
  port = 8080
}

HOCON permet la substitution de variable. Une variable, une fois définie, peut être réutilisée à d’autres endroits dans la configuration, ce qui réduit la redondance de la déclaration.

base-url = "https://example.com"
api-url = ${base-url}"/api"

YAML propose quelque chose d’équivalent, bien que moins élégamment à mon avis, avec l’utilisation d’ancres et d’alias:

base-url: &base "https://example.com"
api-url: *base "/api"

HOCON permet également l’inclusion de fichiers de configuration, ce qui facilite leur composition.

HOCON supporte la concaténation de variables. Lorsque deux variables sont concaténées, les caractéristiques de la seconde complètent ou écrasent ceux de la première. Cette fonctionnalité peut être utilisée pour « hériter » des configurations:

data-center-generic = { cluster-size = 6 }
data-center-east = ${data-center-generic} { name = "east" }

Dans cet exemple, la seconde ligne a le même effet que la déclaration directe suivante:

data-center-east {
  cluster-size = 6 
  name = "east" 
}

La concaténation de liste permet, par exemple, l’extension de chemins:

path = [ /bin ]
path = ${path} [ /usr/bin ]

Adoption

Bien que moins populaire que JSON et YAML, HOCON fait figure de standard dans certaines communautés logicielles. Étant originellement développé par TypeSafe, il est nativement supporté par plusieurs produits associés à cette entreprise, tels que le framework Web Play ainsi que la bibliothèque Akka. Plus généralement, ce format de fichier bénéficie d’une adoption au sein des projets en Java et Scala ainsi que, de manière plus anecdotique, en .Net.

HOCON est le principal format de configuration pour les produits de TIBCO Streaming ainsi que pour l’outil de gestion de configuration Puppet.

Conclusion

HOCON est un format de configuration bien moins connu que JSON et YAML, mais qui, par sa concision et certaines de ses fonctionnalités, mérite qu’on considère son utilisation. Simple et efficace, la difficulté à créer de nouveaux parseurs pour ce langage limite sa diffusion, si bien que vous vous orienterez probablement vers d’autres options si votre système ou langage de programmation préféré ne le supporte pas.

Son champ applicatif s’arrête là où commence les systèmes de templates: si vous avez besoin de templates conséquents, de configurations conditionnelles ou d’autres aspects dynamiques, ce n’est pas un format de configuration que vous cherchez, mais un langage de programmation, éventuellement spécifique à votre domaine. Vous pourriez alors par exemple combiner HOCON avec un moteur de template tel que Jinja (en Python) ou Twirl (en Java/Scala).

Laisser un commentaire