Reading and Writing YAML to a File in Node.js/JavaScript

Spread the love
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Introduction
In last few years YAML, which stands for YAML Ain’t Markup Language, has become very popular for use in storing data in a serialized manner, typically configuration files. Since YAML essentially is a data format, the YAML specification, is fairly brief. Thus, the only functionality required of YAML libraries is the ability to parse or generate YAML-formatted files.
In this article we’re going to see how you can use YAML with a Node.js application. We will start by seeing how data is stored in a YAML file, followed by loading that data into a JavaScript object. Lastly, we will learn how to store a JavaScript object in a YAML file.
There are a few popular Node libraries used for parsing and generating YAML: yaml and js-yaml. js-yaml is the more popular of the two libraries, so that’s what we’ll focus on for this article.
Before we move further, there are a few prerequisites for this tutorial. You should have a basic understanding of JavaScript’s syntax, specifically for the Node.js runtime. You’ll also want to have Node.js and NPM installed on your system to follow along. Other than that, the tutorial is quite simple and easy to follow for beginners.
Installation
As with any Node package, the installations is pretty simple using NPM:
$ npm install js-yaml

Just be sure to use the correct flags for saving the dependency in your package.json file. For example, if js-yaml is only used for development purposes, then use –save-dev, otherwise use –save if it’s used in the production environment of your app.
You can verify that it’s correctly installed by opening the REPL from the same directory and importing the package with the following:
$ node
> const yaml = require(‘js-yaml’)
>

The js-yaml library also supports CLI usage, which allows you to inspect YAML files from the command line. You can enable this by installing the package globally:
$ npm install -g js-yaml

Reading YAML Files in Node.js
We’ll start out by reading a YAML-formatted file and parsing it in to a JS object. For the sake of this tutorial, let’s say we have a file, data.yaml, which has the following contents:
— # Article data
title: “Reading and Writing YAML to a File in Node.js/JavaScript”
url path: “/reading-and-writing-yaml-to-a-file-in-node-js-javascript”
domain: “stackabuse.com”
port: 443
is-https: true
meta:
published-at: “Nov. 1st, 2019”
author:
name: “Scott Robinson”
contact: “[email protected]
tags:
– javascript
– node.js
– web development

To read and parse this file, we’ll be using the .safeLoad() method:
// read.js
const fs = require(‘fs’);
const yaml = require(‘js-yaml’);

try {
let fileContents = fs.readFileSync(‘./data.yaml’, ‘utf8’);
let data = yaml.safeLoad(fileContents);

console.log(data);
} catch (e) {
console.log(e);
}

Running this code will output the following:
$ node read.js
{ title: ‘Reading and Writing YAML to a File in Node.js/JavaScript’,
‘url path’: ‘/reading-and-writing-yaml-to-a-file-in-node-js-javascript’,
domain: ‘stackabuse.com’,
port: 443,
‘is-https’: true,
meta:
{ ‘published-at’: ‘Nov. 1st, 2019’,
author: { name: ‘Scott Robinson’, contact: ‘[email protected]’ },
tags: [ ‘javascript’, ‘node.js’, ‘web development’ ] } }

You can see that the data in the YAML file is now converted to JS literals and objects in the same structure as the file.
The .safeLoad() method is recommended for parsing YAML content since it is safe for untrusted data. One limitation worth noting is that this method does not support multi-document sources. If you’re familiar with YAML, you’ll know that YAML can contain multiple “documents” within a single file, which are separated with the — syntax. For example:
— # Programming language
language: “JavaScript”
created-at: “December 4, 1995”
domain: “stackabuse.com”
creator: “Brendan Eich”
— # Website
domain: “wikipedia.org”
created-at: “January 15, 2001”
num-languages: 304
num-articles: 51360771
creator:
– Jimmy Wales
– Larry Sanger

Loading this file with .safeLoad() will throw an exception. Instead, you should use the .safeLoadAll() method, like so:
// read-all.js
const fs = require(‘fs’);
const yaml = require(‘js-yaml’);

try {
let fileContents = fs.readFileSync(‘./data-multi.yaml’, ‘utf8’);
let data = yaml.safeLoadAll(fileContents);

console.log(data);
} catch (e) {
console.log(e);
}

This results in an array of parsed YAML documents:
$ node read-all.js
[ { language: ‘JavaScript’,
‘created-at’: ‘December 4, 1995’,
domain: ‘stackabuse.com’,
creator: ‘Brendan Eich’ },
{ domain: ‘wikipedia.org’,
‘created-at’: ‘January 15, 2001’,
‘num-languages’: 304,
‘num-articles’: 51360771,
creator: [ ‘Jimmy Wales’, ‘Larry Sanger’ ] } ]

Another method worth mentioning is the .load() method, which is very similar to .safeLoad(), except that it supports all YAML schema types. The extra supported types are specific to JavaScript (!!js/undefined, !!js/regexp, and !!js/function) and you must absolutely trust the data in these YAML files since it can load untrusted code.
For example, a function can be defined in YAML like the following:
‘toString’: ! function() {console.log(‘Malicious code execuited!’);}

That tag tells our YAML library to parse it as a function, which can then be executed later. As pointed out in the documentation, one common method that is executed on JS objects is toString, which we can exploit like this:
// unsafe.js
const yaml = require(‘js-yaml’);

let yamlStr = “‘toString’: ! function() {console.log(‘Malicious code execuited!’);}”;
let loadedYaml = yaml.load(yamlStr) + ”;
console.log(loadedYaml);

And running this code shows that the console.log method is indeed executed:
$ node unsafe.js
Malicious code execuited!
undefined

Writing YAML to Files in Node.js
Now that you know how to read YAML files with Node.js, let’s see how we can write JavaScript objects/data to a YAML file.
For this example, we’ll be using the following JS object, which you may recognize from the previous examples:
let data = {
title: ‘Reading and Writing YAML to a File in Node.js/JavaScript’,
‘url path’: ‘/reading-and-writing-yaml-to-a-file-in-node-js-javascript’,
domain: ‘stackabuse.com’,
port: 443,
‘is-https’: true,
meta: {
‘published-at’: ‘Nov. 1st, 2019’,
author: {
name: ‘Scott Robinson’,
contact: ‘[email protected]
},
tags: [
‘javascript’, ‘node.js’, ‘web development’
]
}
};

In order to serialize this object and save it to a YAML-formatted file, we’ll use the .safeDump() method, which again uses js-yaml’s DEFAULT_SAFE_SCHEMA:
// write.js
const fs = require(‘fs’);
const yaml = require(‘js-yaml’);

let data = { /* Same as above */};

let yamlStr = yaml.safeDump(data);
fs.writeFileSync(‘data-out.yaml’, yamlStr, ‘utf8’);

Executing this code will write out a YAML file that looks like this:
title: Reading and Writing YAML to a File in Node.js/JavaScript
url path: /reading-and-writing-yaml-to-a-file-in-node-js-javascript
domain: stackabuse.com
port: 443
is-https: true
meta:
published-at: ‘Nov. 1st, 2019’
author:
name: Scott Robinson
contact: [email protected]
tags:
– javascript
– node.js
– web development

This output is almost identical to the original YAML we read earlier in the article, except that the document separator (—) is not included.
Data Types
It’s important to keep in mind that not all JavaScript data types can be directly serialized to YAML, and vice versa. In some cases, the closest data type will be used when possible if it’s not directly supported. For example, a YAML !!seq type will be parsed as a JavaScript array.
According to the js-yaml documentation, the following data types are supported:
YAML Type
Example
JS Type

!!null

null

!!bool

true

bool

!!int

3

number

!!float

3.1415

number

!!binary

c3RhY2thYnVzZS5jb20=

buffer

!!timestamp

‘2013-08-15’

date

!!omap

[ … ]

array of key-value pairs

!!pairs

[ … ]

array or array pairs

!!set

{ … }

array of objects with given keys and null values

!!str

‘…’

string

!!seq

[ … ]

array

!!map

{ … }

object

As mentioned earlier, other JS-specific types can also be supported, but only if you aren’t using the “safe” methods.
Conclusion
YAML is an increasingly popular format used to structure data for applications, typically as configuration files, but also as a replacement for anything that JSON is used for. Due to its high flexibility and easy to read syntax, it is quickly replacing JSON in many projects, although both still have their place.
In this article we showed how you can use the js-yaml library to parse YAML files to JavaScript objects in Node.js and how you can serialize JavaScript objects to a YAML file. We also showed what JS types are used for various YAML data types. For more details on this library, check out the official documentation.

X ITM Cloud News

Emily

Next Post

Object Oriented Design Principles in Java

Sun Nov 24 , 2019
Spread the love          Introduction Design principles are generalized pieces of advice or proven good coding practices that are used as rules of thumb when making design choices. They’re a similar concept to design patterns, the main difference being that design principles are more abstract and generalized. They are high-level pieces of […]
X- ITM

Cloud Computing – Consultancy – Development – Hosting – APIs – Legacy Systems

X-ITM Technology helps our customers across the entire enterprise technology stack with differentiated industry solutions. We modernize IT, optimize data architectures, and make everything secure, scalable and orchestrated across public, private and hybrid clouds.

This image has an empty alt attribute; its file name is x-itmdc.jpg

The enterprise technology stack includes ITO; Cloud and Security Services; Applications and Industry IP; Data, Analytics and Engineering Services; and Advisory.

Watch an animation of  X-ITM‘s Enterprise Technology Stack

We combine years of experience running mission-critical systems with the latest digital innovations to deliver better business outcomes and new levels of performance, competitiveness and experiences for our customers and their stakeholders.

X-ITM invests in three key drivers of growth: People, Customers and Operational Execution.

The company’s global scale, talent and innovation platforms serve 6,000 private and public-sector clients in 70 countries.

X-ITM’s extensive partner network helps drive collaboration and leverage technology independence. The company has established more than 200 industry-leading global Partner Network relationships, including 15 strategic partners: Amazon Web Services, AT&T, Dell Technologies, Google Cloud, HCL, HP, HPE, IBM, Micro Focus, Microsoft, Oracle, PwC, SAP, ServiceNow and VMware

.

X ITM