YAML in Spring Boot

YAML In Spring Boot | YAML stands for yet another markup language. It is a file (like text format) that stores data in the key-value format without any duplicate words/levels. But still, Java supports key-value pairs input using java.util.Properties.

YAML is another format of writing properties. YAML file internally converted into Properties format using Snake YAML API.

What is the level of the key? The dot symbol (.) in keys creates a new/next level. Example:- mp.app.code=ABC; Here “my” 1st level in the key, “app” second level in the key, “code” third level in the key.

In the properties file, we use keys that may have more duplicate levels. For example in application.properties:-

spring.datasource.driver-class-name=OracleDriver
spring.datasource.url=jdbc:oracle
spring.datasource.username=system
spring.datasource.password=abc

However, the YML file does not contain duplicate levels. The same can be written in YML as (application.yml):-

spring:
    datasource:
        driver-class-name: OracleDriver
        url: jdbc:oracle
        username: system
        password: abc

Rules to write YAML file from properties file:-

  1. Replace dot(.) and equals(=) with colon(:)
  2. After the colon, move the next level/word to the next line [Do not write duplicates].
  3. Before every new level(not 1st level) provide spaces (at least one) [Space count must match for the same level] (tab is also valid).
  4. Finally, for value, give exactly one space/tab between the last level and data.

In _.properties:-

my.app.id=10
my.app.code=A

In _.yml:-

my:
    app:
        id: 10 // one space only between last level and value
        code: A

We don’t need any plugin/configuration or a seperate dependency to work with YML files in spring boot. In maven depencies, we can find snakeyml-version.jar file which is responsible for converting data given in YML into the java.util.Properties.

snakeyaml

More Examples on Writing YML

application.properties:-

my.app.code=A
my.app.model=B
my.grade.service=new
my.grade.cost=600

application.yml:-

my:
    app:
        code: A
        model: B
    grade:
        service: new
        cost: 600

Example-2:- application.properties:-

spring.jpa.show-sql=true
spring.jpa.ddl-auto=create
spring.hikari.size=20
spring.hikari.name=hrk

application.yml:-

spring:
    jpa:
        show-sql: true
        ddl-auto: create
    hikari:
        size: 20
        name: knowprogram

Example-3: application.properties:-

spring.jpa.hibernate.auto-create=true
spring.jpa.show-sql=true
spring.jpa.hibernate.format.export=new
spring.jpa.model=entity
spring.jpa.grade.code=accept

application.yml:-

spring:
    jpa:
        hibernate:
            auto-create: true
            format:
                export: new
        show-sql: true
        model: entity
        grade:
            code: accept

Example-4: application.properties-

my.grade.mode=A
spring.format.text=one
my.accept.mode=new
spring.jpa.show=true
my.grade.state=SA
spring.format.active=true
spring.jpa.final=mode

application.yml:-

my:
    grade:
        mode: A
        state: SA
    accept:
        mode: new
spring:
    format:
        text: one
        active: true
    jpa:
        show: true
        final: mode

YAML in Spring Boot Example

Create a new Spring boot project. In the src/main/resources folder where the application.properties file resides, create another file:- application.yml

application.yml

In application.yml:-

my:
  app:
    id: 10
    name: abc
    cost: 500.0

Create a runner class to read the data and test it:-

package com.knowprogram.demo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Component
@Getter
@Setter
@ToString
public class DataReadRunner implements CommandLineRunner {
    
    @Value("${my.app.id}")
    private Integer pid;
    
    @Value("${my.app.name}")
    private String name;
    
    @Value("${my.app.cost}")
    private Double pcost;

    @Override
    public void run(String... args) throws Exception {
        System.out.println(this);        
    }
}

Run the application. In console:-

If we do not follow proper rules to write __.yml file then SnakeYAML API throws data parsing exception like org.yaml.snakeyaml.scanner.ScannerException: mapping values are not allowed here.

Duplicate keys are not allowed in YAML. Voliating this will cause org.yaml.snakeyaml.constructor.DuplicateKeyException: while constructing a mapping.

If some key is present in both the application.properties file and the application.yml file then the application.properties file will get higher priority.

In application.properties:-
my.app.id=99999

In application.yml:-

my:
  app:
    id: 10
    name: abc
    cost: 500.0

Using the same DataReadRunner, run the application. Output in the console:-
DataReadRunner(pid=99999, name=abc, pcost=500.0)

Spring boot will first search for the keys in the application.properties file, if not available then go to the application.yml file.

STS IDE also provides built in option to convert properties file to YML file. Select the properties file => right click => You will see “Convert .properties to .yml” option.

convert .properties to .yml file

YAML with @ConfigurationProperties

Prerequisite:- Bulk Loading of Properties in Spring Boot

In application.yml:-

my:
  app:
    pid: 10
    name: abc
    pcost: 500.0

Runner class:-

package com.knowprogram.demo;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Component
@Getter
@Setter
@ToString
@ConfigurationProperties(prefix = "my.app")
public class DataReadRunner implements CommandLineRunner {

    private Integer pid;

    private String name;

    private Double pcost;

    @Override
    public void run(String... args) throws Exception {
        System.out.println(this);
    }
}

In Console:-

To represent array/list/set dash (-) symbol is used to represent the index in order.
List models;
Set models;
String[ ] models;

my:
  app:
    models:
      - A
      - B
      - C

For map:- Map<String, Integer> grades;

my:
  app:
    grades:
      eng: 90
      mat: 60
      sci: 40

Application Example

In application.yml file:-

my:
  app:
    models:
      - A
      - B
      - C
    grades:
      g1: 10
      g2: 20

In Runner class:-

package com.knowprogram.demo;

import java.util.List;
import java.util.Map;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Component
@Getter
@Setter
@ToString
@ConfigurationProperties(prefix = "my.app")
public class DataReadRunner implements CommandLineRunner {
    
    private List<String> models;
    private Map<String, Integer> grades;

    @Override
    public void run(String... args) throws Exception {
        System.out.println(this);
    }
}

In Console:-

@ConfigurationProperties With Class and Object

Student.java:-

package com.knowprogram.demo;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class Student {
    private Integer sid;
    private String sname;
    private Double sfee;
}

In application.yml:-

my:
  app:
    student:
      sid: 111
      sname: Jerry
      sfee: 1000

In runner.class:-

package com.knowprogram.demo;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Component
@Getter
@Setter
@ToString
@ConfigurationProperties(prefix = "my.app")
public class DataReadRunner implements CommandLineRunner {
    
    private Student student;

    @Override
    public void run(String... args) throws Exception {
        System.out.println(this);
    }
}

In console:-

If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or do you find anything incorrect? Let us know in the comments. Thank you!

Leave a Comment

Your email address will not be published. Required fields are marked *