2024-10-05T22:35:07 Status: #moc Tags: #technology #standards #data #markup #json #yaml #tutorial Links: [[Technology]] | [[Standards]] | [[YAML]] | [[JSON]] # YAML Tutorial ## Introduction [[YAML]], which stands for "YAML Ain't Markup Language" (a recursive acronym), is a human-readable serialization language. It is commonly used for configuration files and data exchange between languages with data structures. YAML emphasizes readability and is designed to be friendly to humans, making it an excellent choice for settings where configuration files are edited by hand. ![[yaml-tutorial.png]] This Tutorial aims to help familiarize you with key YAML concepts quickly. For further details beyond this tutorial, you can refer to the [Language Overview in the current YAML 1.2.2 Specs](https://yaml.org/spec/1.2.2/#chapter-2-language-overview). And for a quick introduction to YAML, please listen to the companion episode [YAML Introduction](https://podcasters.spotify.com/pod/show/xmlaficionado/episodes/YAML-Introduction-e2pion3) on my new [XML Aficionado Podcast](https://podcasters.spotify.com/pod/show/xmlaficionado): ![[YAML Tutorial.wav]] ## Basic YAML Syntax YAML syntax is designed to be clear and concise, allowing for easy data representation using maps (dictionaries), arrays (lists), and scalars (strings, integers, etc.). ### Maps/Dictionaries Maps or dictionaries are key-value pairs. Keys are unique and followed by a colon. ```yaml person: name: John Doe age: 34 occupation: Software Engineer ``` Note that there must be at least one whitespace after the colon. ### Arrays/Lists Arrays or lists are collections of items. Each item in the list is preceded by a `-`. ```yaml pets: - Dog - Cat - Parrot ``` ### Literals Scalars include literals like strings, booleans, integers, floats, dates, etc. YAML interprets these based on the context. ```yaml string: "Hello, World!" another_string: 'Single quotes are good, too' number: 42 boolean: true date: 2024-10-06 timestamp: 2024-10-06T09:26:17Z float: 3.14159 # More esoteric concepts, such as NAN and NULL are also covered by YAML, # but may require explicit tags to denote the datatype: not_a_number: !!float .nan null: !!null null ``` Quotes are optional for strings unless they contain special characters. ### Comments YAML [comments](https://yaml.org/spec/1.2.2/#comments) begin with an octothorpe (also called a “hash”, “sharp”, “pound” or “number sign” - “`#`”). ``` yaml # Comments can be on their own line, or inline at the end of lines hr: 65 # Home runs avg: 0.278 # Batting average rbi: 147 # Runs Batted In ``` ## Indentation YAML is indentation sensitive, similar to [[Python]]. [Indentation](https://yaml.org/spec/1.2.2/#indentation-spaces) in YAML expresses [block collections](https://yaml.org/spec/1.2.2/#block-collection-styles) and signifies hierarchy and nesting. Unlike many other languages, YAML primarily uses indentation rather than braces or brackets to define structure. ``` yaml person: name: Alice details: age: 28 city: New York ``` Here, `name` and `details` are nested under `person`, and `age` and `city` are nested under `details`. Note that indentation should be done using spaces, not tabs, and you need to maintain consistent indentation levels. Next, let's revisit the basic collection types in a bit more detail... ## Mappings [Mappings](https://yaml.org/spec/1.2.2/#mapping) are collections of key-value pairs, similar to dictionaries in Python or objects in JavaScript. Each key-value pair is separated by a colon and a space. Nested mappings are created through indentation. ```yaml database: host: localhost port: 3306 username: root password: secret ``` ### Inline Mappings YAML also has [flow styles](https://yaml.org/spec/1.2.2/#flow-style-productions), so you can also write [flow mappings](https://yaml.org/spec/1.2.2/#flow-mappings) in a single line using curly braces, which is essentially equivalent to the corresponding [[JSON]] syntax: ``` yaml database: { host: localhost, port: 3306, username: root, password: secret } ``` This is especially useful, when you want to express mappings of mapping, for example: ``` yaml Mark McGwire: {hr: 65, avg: 0.278} Sammy Sosa: { hr: 63, avg: 0.288, } ``` ## Block Sequences Sequences represent ordered lists of items. Each item in a sequence starts with a hyphen `-` followed by a space. Items are indented under their parent key. ```yaml fruits: - Apple - Banana - Cherry ``` ### Inline Sequences Just like with mapping, YAML offers [flow sequences](https://yaml.org/spec/1.2.2/#flow-sequences), which are written in square brackets in a single line, separated by commas, which is again equivalent to the corresponding [[JSON]] syntax: ``` yaml fruits: [Apple, Banana, Cherry] ``` This is especially useful, when you want to express sequences of sequences, for example: ``` yaml - [name , hr, avg ] - [Mark McGwire, 65, 0.278] - [Sammy Sosa , 63, 0.288] ``` ## Literals Literals are called [scalar content](https://yaml.org/spec/1.2.2/#scalar) in YAML and can be written as folding or block notation. ### Folding Strings Folded strings use `>` for more readable multi-line text, where new lines are replaced with spaces. ```yaml address: > 123 Main Street Anytown, AW 12345 ``` ### Block Strings Block strings are literal blocks using `|` where new lines are preserved. ```yaml bio: | John Doe Software Developer ``` ### Chomp Characters Chomp characters (`-`, `+`, `|`) control how final new lines are handled in block strings. - `-` : Strip the last newline - `+` : Keep all newlines - `|` : Keep one newline ## Advanced YAML Syntax ### Documents Multiple documents can be included in a single file, separated by `---`. Optionally, the end of a document can be indicated by three dots `...` ```yaml --- document: 1 ... --- document: 2 ... ``` ### Schemas and Tags YAML allows specifying data types using explicit tags. ```yaml integer: !!int 123 string: !!str 123 ``` ### Anchors and Alias Anchors (`&`) are used to define duplicate content, and aliases (`*`) are used to reference it. ```yaml default_settings: &defaults resolution: 1920x1080 color: blue custom_settings: <<: *defaults color: red ``` ## Complete Example Here is a full-length example of a YAML file describing an invoice, which uses all of the above concepts and more: ``` yaml --- !<tag:clarkevans.com,2002:invoice> invoice: 34843 date : 2001-01-23 bill-to: &id001 given : Chris family : Dumars address: lines: | 458 Walkman Dr. Suite #292 city : Royal Oak state : MI postal : 48046 ship-to: *id001 product: - sku : BL394D quantity : 4 description : Basketball price : 450.00 - sku : BL4438H quantity : 1 description : Super Hoop price : 2392.00 tax : 251.42 total: 4443.52 comments: Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338. ``` ## YAML vs JSON vs XML It is important to understand that [[YAML]] is a *superset* of [[JSON]], meaning all JSON files are valid YAML files. YAML’s syntax is more human-readable and less verbose, not requiring quotes for strings or commas between elements, and allowing comments, making it an increasingly popular choice for configuration files (see [[YAML Tutorial#Prominent Examples of YAML Usage|examples below]]). For a comparison of the features available in the three languages, please see this table: | Feature | **[[YAML]]** | **[[JSON]]** | **[[XML]]** | | ----------------------- | --------------- | ------------ | -------------- | | Human Readability | Easy | Moderate | Complex | | Verbosity | Low | Moderate | High | | Data Types Support | Rich | Simple | via XML Schema | | Schema Support | via JSON Schema | JSON Schema | [[XML Schema]] | | Comments | Yes | No | Yes | | Path Language | No | No | [[XPath]] | | Query Language | No | No | [[XQuery]] | | Transformation Language | No | No | [[XSLT]] | Both YAML and JSON lack the additional specifications that allow easy identification of individual elements in a document ([[XPath]]), querying of documents ([[XQuery]]), and transformations of documents ([[XSLT]]) that XML provide. However, some developer tools have recently extended the capabilities of those languages to JSON and YAML, for example [XQuery Expressions for JSON](https://www.altova.com/manual/XMLSpy/spyenterprise/xsjson_xqueryexp4json.html) in [[Altova]] [[XMLSpy]]. ## Prominent Examples of YAML Usage ### Configuration Files #### Docker Compose [Docker Compose](https://docs.docker.com/compose/) is a tool for defining and running multi-container applications. Compose simplifies the control of your entire application stack, making it easy to manage services, networks, and volumes in a single, comprehensible YAML configuration file (typically called `compose.yaml`). Then, with a single command, you create and start all the services from your configuration file. ``` yaml services:   licenseserver:     build: licenseserver     ports:       - "8088:8088" # Altova License Server Admin Interface       - "35355:35355" # Altova License Server RPC Interface     volumes:       - licenseserver_data:/var/opt/Altova   flowforceserveradv:     build: flowforceserveradv     environment:       - PYTHONUNBUFFERED=1     ports:       - "8082:8082" # FlowForce Server Advanced Web Interface       - "4646:4646" # FlowForce Server Advanced RPC Interface         - "8087:8087" # RaptorXML Server Interface       - "29800:29800" # DiffDog Server Interface     depends_on:       - licenseserver     volumes:       - flowforceserver_data:/var/opt/Altova   mobiletogetherserveradv:     build: mobiletogetherserveradv     environment:       - PYTHONUNBUFFERED=1     ports:       - "8083:8083" # MobileTogether Server Advanced Client & Web Interface       - "8085:8085" # MobileTogether Server Advanced Admin Interface     depends_on:       - licenseserver     volumes:       - mobiletogetherserver_data:/var/opt/Altova volumes:   licenseserver_data:   flowforceserver_data:   mobiletogetherserver_data: ``` #### Kubernetes Manifests Kubernetes uses YAML files extensively for defining applications, deployments, services, and other resources in the form of manifests for [managing workloads](https://kubernetes.io/docs/concepts/workloads/management/). Here is an example of an nginx manifest: ``` yaml apiVersion: v1 kind: Service metadata: name: my-nginx-svc labels: app: nginx spec: type: LoadBalancer ports: - port: 80 selector: app: nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 ``` #### Ansible Ansible is an open-source automation system that allows task automation and simplification of workflows. Ansible uses YAML for its [playbooks](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_intro.html), offering a human-readable approach to scripting automation. Here is an example of an Ansible playbook: ``` yaml --- - name: Update web servers hosts: webservers remote_user: root tasks: - name: Ensure apache is at the latest version ansible.builtin.yum: name: httpd state: latest - name: Write the apache config file ansible.builtin.template: src: /srv/httpd.j2 dest: /etc/httpd.conf - name: Update db servers hosts: databases remote_user: root tasks: - name: Ensure postgresql is at the latest version ansible.builtin.yum: name: postgresql state: latest - name: Ensure that postgresql is started ansible.builtin.service: name: postgresql state: started ``` #### Espanso Espanso is a cross-platform text expansion utility that replaces keywords with expanded text blocks as you are typing. Espanso uses YAML configuration files to define the rules for [matches](https://espanso.org/docs/matches/basics/). ``` yaml # Print the current date in US format - trigger: ":usdate" replace: "{{mydate}}" vars: - name: mydate type: date params: format: "%m/%d/%Y" # Print the current date in ISO format - trigger: ":isodate" replace: "{{mydate}}" vars: - name: mydate type: date params: format: "%Y-%m-%d" # Various arrows in different directions - trigger: ":->" replace: "→" - trigger: ":<-" replace: "←" - trigger: ":^" replace: "↑" - trigger: ":v" replace: "↓" - trigger: ":<>" replace: "↔" ``` ### Static Site Generators #### Jekyll Jekyll transforms plain text into static websites and blogs without resorting to databases, comment moderation, or pesky updates needing to be installed. Content is written in Markdown, Liquid, or HTML and styled with [[CSS]]. Jekyll uses YAML [front matter](https://jekyllrb.com/docs/front-matter/) blocks for page metadata. ### API Definitions #### OpenAPI The OpenAPI Specification (OAS) defines a standard, language-agnostic interface to HTTP APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined, a consumer can understand and interact with the remote service with a minimal amount of implementation logic. An OpenAPI definition can then be used by documentation generation tools to display the API, code generation tools to generate servers and clients in various programming languages, testing tools, and many other use cases. An OpenAPI document that conforms to the OpenAPI Specification is itself a JSON object, which may be represented either in [[JSON]] or [[YAML]] format. ``` yaml title: "Sample Pet Store App" summary: "A pet store manager." description: "This is a sample server for a pet store." termsOfService: https://example.com/terms/ contact: name: "API Support" url: https://www.example.com/support email: support@example.com license: name: "Apache 2.0" url: https://www.apache.org/licenses/LICENSE-2.0.html version: 1.0.1 ``` ## YAML Tools In Altova **XMLSpy v2024r2**, we’ve introduced comprehensive YAML support alongside XML and JSON. Support includes: - **[YAML Editor](https://www.altova.com/xmlspy-xml-editor/yaml-editor)**: A full-featured environment with syntax highlighting, source folding, and well-formedness checking. - **YAML Validation against JSON Schema**: Ensuring data integrity and adherence to standards. - **One-Click Conversion**: Seamlessly switch between [[XML]], [[JSON]], and [[YAML]]. ![[yaml-editor.avif]] YAML is also now supported by the [AI-Assistant in XMLSpy](https://www.altova.com/xmlspy-xml-editor/ai-assistant), so you can ask the [[AI]] to provide [[YAML]] configuration files for a particular [[Kubernetes]] Deployment of [[MobileTogether]] Server, for example, and it will gladly oblige. And for [hyper-performance validation](https://www.altova.com/raptorxml), **RaptorXML Server** now supports YAML alongside XML, JSON, and XBRL standards. ## Curious and Unexpected Facts about YAML - **Recursive Acronym**: YAML continues the long-standing tradition of recursive acronyms in computing, including GNU, PHP, PIP, PNG, RPM, and SPARQL. YAML stands for "YAML Ain't Markup Language," making it a recursive acronym. However, it should be noted that YAML originally stood for "Yet Another Markup Language". This dual definition has some historical significance. - **Date Handling**: YAML can natively understand dates, which is not a feature in JSON. - **Whitespace Sensitivity**: While making YAML readable, its sensitivity to whitespace can lead to errors. - **Complex Syntax**: YAML’s simplicity can be misleading as it supports complex features like anchors and aliases, which can make certain YAML documents challenging to interpret. ## Conclusion YAML's human-friendly design has made it a popular choice for configuration files, data exchange, and more, especially in DevOps and cloud computing environments like Kubernetes and Ansible. Its ability to represent data structures in a readable format makes it ideal for a wide range of applications, despite its whitespace sensitivity and potential for complexity. Understanding YAML is crucial for professionals in software development, especially those working in infrastructure, cloud, and automation. --- # References - Official YAML website: https://yaml.org/ - Current YAML 1.2.2 specifications: https://yaml.org/spec/1.2.2/ - https://www.altova.com/xmlspy-xml-editor/yaml-editor