YAML (YAML Ain't Markup Language) 이해하기

    YAML

    기존에는 XML과 JSON으로 어떤 값들을 저장하고 사용했다. 그러나, XML과 JSON은 사용하기가 복잡하다는 점 때문에 2001년에 Clark Evans에 의해 최초 제안되었다. 원래 이름은 'YAML은 Markup 언어가 아니다(YAML Ain't Markup Language)'라는 뜻으로 불렸으며, 동시에 또 다른 마크업 언어(Yet Another Markup Language)라는 뜻으로도 불리기도 한다. K8S, Ansible, Spring Boot 등의 환경설정에도 쓰이면서 개발자들에게도 많이 친숙한 편이다. (사실 모르면 안되는 축으로 바뀌고 있다.)

    파일 확장자는 .yaml 혹은 .yml로 사용하며, 많은 사람들이 발음하는 바로는 /야믈/이라고 주로 읽는다.

     

    주요 문법

    • 공백 문자들로 기본 구조를 구성한다. 단, 탭(tab)은 사용되지 않는다.
    • key: value 형태로 표시하되, : 다음에 공백 문자가 와야 한다. 붙여쓰면 오류.
    • #로 주석을 표시한다. 문장 중 어느 곳에든지 쓸 수 있다.
    • 문장 앞에 하이픈(-)을 적어주면 리스트의 시작이 된다. 그리고, 하이픈으로 표시하면 한 줄에 한 요소를 나열하는 방식의 표기를 뜻한다.
    • 리스트를 [a, b, c] 형식으로 표현할 수도 있다. (한 라인에 표기하기)
    • 문자열이라 하더라도 기본적으로 따옴표 없이 쓸 수 있다. 필요에 따라 '' 또는 ""로 묶어 쓸 수 있다.
    • 여러 라인의 문자열은 | 또는 > 를 사용하여 손쉽게 표기할 수 있다.
    • 여러 문서의 경우, 세 개의 하이픈(---)으로 구분지을 수 있다.
    • 문서의 끝은 ....로 표기한다.
    • 반복되는 노드는 알리아스를 선언하고, 참조할 수 있다.
      • 선언은 & 로 한다.
      • 참조는 * 로 한다.




    공부/ 검증시 참고 사이트

    사실 주요 문법이라고 위에 옮겨놨지만, 와닿지 않는다. 결국, 잘 동작하는지 보려면 검사를 해봐야 하고, 특히 우리가 익숙한 JSON으로도 변환해서 차이점을 비교해 보면 YAML을 이해하는데 도움이 될 것이다.

    https://yaml-online-parser.appspot.com/

    https://www.convertjson.com/yaml-to-json.htm

    https://www.json2yaml.com/convert-yaml-to-json

    를 접속해보자. 그리고, YAML 예제를 입력해서 JSON으로 어떻게 변환되는지 확인할 수 있다. 그리고, 입력한 YAML에 문법상 오류가 있다면 오류 메시지가 출력되고, 변환이 제대로 되지 않을 것이다. 이 사이트들 모두 키 입력을 하는 즉시, 파싱 및 변환을 수행해 주기 때문에 곧바로 이상 유무 및 문맥 확인/학습에 도움을 줄 수 있다.

     

    주요 문법 확인 예

    위에서 소개한 주요 규칙들로 이뤄진 문법을 YAML로 작성하고, JSON으로 변경된 값을 비교하면서 이해해 보자.

    주석

    // YAML
    # students
    name: John
    major: Math
    
    // JSON
    {
      "name": "John",
      "major": "Math"
    }

    YAML/JSON 변환 결과에서 보듯, YAML에서는 주석 표기가 가능하지만, _comment 엘리먼트를 사용하거나 JSON5를 사용하는 방법도 있으나 JSON에서는 기본적으로 주석 표기를 지원하지 않는다.

     

    Key: Value 표기

    기본적으로 key와 value는 콜론(:)을 기준으로 구분한다. 보다 정확히 밀하자면 콜론을 쓰고 그 뒤에 공백문자까지 표기해 줘야 key와 value를 구분할 수 있다.

    콜론(:) 뒤에 공백이 없는 경우부터 살펴 보자.

    # YAML
    key:value
    
    # JSON
    "key:value"

    하나의 스트링으로 있는 그대로 인식된 것을 확인할 수 있다. 반면, key와 value 사이의 콜론 뒤에 공백 문자를 두면, 결과는 달라진다.

    # YAML
    key: value
    
    # JSON
    {
      "key": "value"
    }

     

    리스트 표현

    여러 개의 아이템을 나열하는 리스트는 간단한 경우는 대괄호로, 복잡한 경우는 하위 리스트에 하이픈(-)으로 시작하는 하위 엘리먼트로 표현할 수 있다. 단순하게 한줄로 표현하는 방법부터 살펴보면,

    # YAML
    students: [Mark, Julie, Tommy]
    
    # JSON
    {
      "students": [
        "Mark",
        "Julie",
        "Tommy"
      ]
    }

    이와 동일한 표현으로 하이픈을 사용하면 다음과 같다.

    @ YAML
    students:
      - Mark
      - Julie
      - Tommy
    
    @ JSON
    {
      "students": [
        "Mark",
        "Julie",
        "Tommy"
      ]
    }

    단순한 리스트의 나열이 아니라, 보다 복잡한 구조체의 리스트를 표현하고자 한다면 다음과 같은 형식을 사용할 수 있을 것이다.

    # YAML
    students:
      - name: Mark
        major: Math
        age: 20
      - name: Julie
        major: Arts
        age: 23
      - name: Tommy
        major: Music
        age: 25
    
    # JSON
    {
      "students": [
        {
          "name": "Mark",
          "major": "Math",
          "age": 20
        },
        {
          "name": "Julie",
          "major": "Arts",
          "age": 23
        },
        {
          "name": "Tommy",
          "major": "Music",
          "age": 25
        }
      ]
    }

    위와 동일한 결과를 얻기 위해, 만약 한 줄로 표현하는 방식의 YAML을 사용하겠다고 한다면, 다음과 같이 표현할 수 있을 것이다. 다만, 가독성이 오히려 떨어지고 작성하기 더 불편해 질 것이다.

    # YAML
    students: [{name: Math, major: Math, age: 20}, {name: Julie, major: Arts, age: 23}, {name: Tommy, major: Music, age: 25}]

     

    따옴표는 필요할 때만 사용 가능

    JSON을 작성할 때는 기본적으로 따옴표를 써줘야 하지만, YAML을 쓸 때는 기본적으로 따옴표를 거의 안 써도 된다.

    # YAML
    name: Mark
    address1: San Francisco
    address2: "San Hoje"
    address3: 'Los Angeles'
    ratio1: 1:2 # weird
    ratio2: "1:2"
    ratio3: '1:2'
    
    # JSON
    {
      "name": "Mark",
      "address1": "San Francisco",
      "address2": "San Hoje",
      "address3": "Los Angeles",
      "ratio1": 3720,
      "ratio2": "1:2",
      "ratio3": "1:2"
    }

     

    따옴표의 차이: single quotes vs. double quotes

    앞서 기술한 바와 같이 YAML에서는 보통 따옴표를 안 써도 되지만, 써야 한다면 두 따옴표의 기능의 차이도 한 번 정도는 짚을 가치가 있다.

    # YAML
    string1: "\t tab \n NL"
    string2: '\t tab \n NL'
    
    # JSON
    {
      "string1": "\t tab \n NL",
      "string2": "\\t tab \\n NL"
    }

    인용해야할 문자 데이터 중, 특수문자가 들어간다면 일단 따옴표를 써야 한다고 인식하자. 홑따옴표와 쌍따옴표의 차이는 escape sequence 처리 여부이다. 쌍따옴표는 escape sequence 처리를 해주고, 홑따옴표는 주어진 그대로 문자열 처리한다. 따라서, \n을 쌍따옴표로 묶으면 개행문자로 인식하고, 홑따옴표로 묶으면 \n로 처리해 줄 것이다.

     

    boolean 값 표현 가능

    yes, no, True, TRUE, False, FALSE 등을 지정하면 boolean 값으로 인식한다. 만약 이 값을 문자열로 전달하고자 한다면 따옴표로 싸줘야 한다.

    # YAML
    # True values
    - key: true
    - key: True
    - key: yes
    
    # False values
    - key: false
    - key: False
    - key: no  
    
    # JSON
    [
      {
        "key": true
      },
      {
        "key": true
      },
      {
        "key": true
      },
      {
        "key": false
      },
      {
        "key": false
      },
      {
        "key": false
      }
    ]

    결과에서 보다시피, true/True/yes라고 기록한 값은 JSON에서는 모두 true로 인식되고 있으며, false/False/no라고 기록한 값은 모두 false로 인식된다.

     

    Alias = 변수

    재사용하는 값 또는 구조체 등은 변수로 선언해 두면 편리할 것이다.

    & 로 변수를 선언하고, * 로 변수를 참조(사용)한다. 변수의 선언과 같이, 선언하지도 않은 변수를 참조하려고 하면 에러가 나듯이 alias도 앞서 선언부터 하고 사용하자.

    # YAML
    - name: &var Jake
    - name: *var
    
    # JSON
    [
      {
        "name": "Jake"
      },
      {
        "name": "Jake"
      }
    ]
    
    # YAML - 에러
    - name: *var
    - name: &var Jake

    앞서 작성한 예제들을 활용하여, 좀더 복잡해 보이는(?) 예제를 작성해 봤다.

    # YAML
    artist:
      artist-alias1: &MK
        name: Mika
        albums:
         - Life in Cartoon Motion
         - The Boy Who Knew Too Much
         - The Origin of Love
         - No Place in Heaven
         - My Name is Michael Holbrook  
    
      artist-alias2: &MJ
        name: Michael Jackson
        albums:
          - Off the Wall
          - Thriller
          - Bad
          - Xcape
          - Michael
          - Invincible
    
    students:
      - name: Mark
        major: Math
        age: 20
        favorites: [*MK, *MJ]
      - name: Julie
        major: Arts
        age: 23
        favorites: [*MK] 
      - name: Tommy
        major: Music
        age: 25

    어떤 학생 들이 있고, 그 학생들이 좋아하는 pop star들을 매핑해 봤는데, 기호가 겹칠 수 있으므로, alias를 사용해 보았다.

    # JSON
    {
      "artist": {
        "artist-alias1": {
          "name": "Mika",
          "albums": [
            "Life in Cartoon Motion",
            "The Boy Who Knew Too Much",
            "The Origin of Love",
            "No Place in Heaven",
            "My Name is Michael Holbrook"
          ]
        },
        "artist-alias2": {
          "name": "Michael Jackson",
          "albums": [
            "Off the Wall",
            "Thriller",
            "Bad",
            "Xcape",
            "Michael",
            "Invincible"
          ]
        }
      },
      "students": [
        {
          "name": "Mark",
          "major": "Math",
          "age": 20,
          "favorites": [
            {
              "name": "Mika",
              "albums": [
                "Life in Cartoon Motion",
                "The Boy Who Knew Too Much",
                "The Origin of Love",
                "No Place in Heaven",
                "My Name is Michael Holbrook"
              ]
            },
            {
              "name": "Michael Jackson",
              "albums": [
                "Off the Wall",
                "Thriller",
                "Bad",
                "Xcape",
                "Michael",
                "Invincible"
              ]
            }
          ]
        },
        {
          "name": "Julie",
          "major": "Arts",
          "age": 23,
          "favorites": [
            {
              "name": "Mika",
              "albums": [
                "Life in Cartoon Motion",
                "The Boy Who Knew Too Much",
                "The Origin of Love",
                "No Place in Heaven",
                "My Name is Michael Holbrook"
              ]
            }
          ]
        },
        {
          "name": "Tommy",
          "major": "Music",
          "age": 25
        }
      ]
    }




    multi line 사용방법

    JSON으로 표현하자면, 데이터내에 \n을 넣어주는 것이 여간 불편한 것이 아니다. YAML에서는 이를 쉽게 지원한다. 몇 가지 사용방법이 있으니 익혀두자. >를 쓰는 방법과, |를 쓰는 방법이 있는데, >는 개행 문자를 스페이스로 치환해주고, 빈 줄 하나가 단독으로 있는 경우만 줄바꿈으로 바꿔준다. |를 쓰면, 기록한 그대로 줄을 바꿔준다. 그래서, >는 folded block scalar로 불리고, |는 literal block scalar로 불린다. 두 기호 끝에 -를 붙이면, 맨끝의 줄바꿈 문자를 포함시키지 않는다.

    # 접기 + 맨끝 개행문자 포함
    # YAML
    paragraph1: >
      abc
      def
      ghi
    
      aab
      ccc
    
    # JSON
    {
      "paragraph1": "abc def ghi\naab ccc\n"
    }
    
    # 접기 + 맨끝 개행문자 제외
    # YAML
    paragraph2: >-
      abc
      def
      ghi
    
      aab
      ccc
    
    # JSON
    {
      "paragraph2": "abc def ghi\naab ccc" 
    
    # 그대로 줄바꿈 + 맨끝 개행문자 포함
    # YAML
    paragraph3: |
      abc
      def
      ghi
    
      aab
      ccc
    
    # JSON
    {
      "paragraph3": "abc\ndef\nghi\n\naab\nccc\n"
    }
    
    # 그대로 줄바꿈 + 맨끝 개행문자 제외
    # YAML
    paragraph4: |-
      abc
      def
      ghi
    
      aab
      ccc
    
    # JSON
    {
      "paragraph4": "abc\ndef\nghi\n\naab\nccc"
    }

     

    공식 사이트

    공식 사이트는 다음과 같다. 세부 스펙 및 업데이트는 아래 사이트를 참고하면 된다.

    https://yaml.org/

    댓글

    Designed by JB FACTORY