In this article I will give you a code example that demonstrates how to make multiple endpoint requests and get one response object.

In the Request Kontent.ai Delivery API in Node.js article I have demonstrated how to get content from your Kontent.ai project with the use of the Delivery API. The article describes how to make one endpoint request at a time. In the real world where you create websites in Node.js, you probably need to request multiple endpoints to render a single page.
Imagine we have a website and need to render a page. The page consists of:
- Master page which is content that is shared across all pages. E. g. navigation, company logo, and footer.
- Page-specific content which is unique for each page.
- Resource strings are small pieces of text that might be shared across multiple pages.
All of these elements are kept separate in our Kontent.ai project because we don't want to have repetitions in our content storage.
I would like to share an elegant approach to how to get all the data with a single method call. Imagine that we make a request with a simple object:
{
masterPage: '?system.type=master',
page: '?system.type=home',
resourceStrings: '?system.type=resource_strings'
}
And get a response in the same format:
{
masterPage: {items: [...]},
page:{items: [...]},
resourceStrings: {items: [...]}
}
Exactly this is possible with the code example below. I won't explain the code step like I did in the previous article because the example in this article is just an enhanced version of the previous one.
const request = require('request'),
requestPromise = require("request-promise"),
Promise = require('bluebird');
'use strict';
/**
* Initializes class with Project ID and Preview API Key that represent a Kentico Kontent project.
* @constructor Delivery
* @param {string} projectID Project ID.
* @param {string} previewKey Preview API Key.
* @example
* var project = new Delivery('82594550-e25c-8219-aee9-677f600bad53', 'ew0KICAiYWxnIjo...QvV8puicXQ');
*/
class Delivery {
constructor(projectID, previewKey) {
this.projectID = projectID;
this.previewKey = typeof previewKey === 'undefined' ? null : previewKey;
}
/**
* Returns promise with data from the Kentico Kontent storage specified by the passed object of filtering URL parameters.
* @method getContent
* @param {object} params Object that contains filtering URL parameters that are used for requesting Kentico Kontent storage.
* @param {boolean} isPreview Flag that controls whether only published or all items should be requested.
* @return {promise} with an object of responses for each passed parameter from the Kentico Kontent storage.
* @example
* // returns
* // {
* // master: {items: [...]},
* // page: {items: [...]}
* // }
* project.getContent({
* master: '?system.type=master',
* page: '?system.type=home'
* }, true)
*/
getContent(params, isPreview) {
// Reject operation if params parameter in not provided
if (typeof params === 'undefined') {
Promise.reject('Please, specify the params parameter in the getContent method.');
}
// Set default state if maethod parameter are not provided
if (typeof isPreview === 'undefined') {
isPreview = false;
}
// Split categories and filtering urls in separate arrays
var categories = [],
values = [];
Object.keys(params).forEach((key, index) => {
categories.push(key);
values.push(params[key]);
});
params = values.slice();
// Create options that will represent your request to the Kentico Kontent storage
let options = Delivery.getOptions(params, this.projectID, this.previewKey, isPreview);
// Request the Kentico Kontent storage and get content from it
return Delivery.getRawData(options)
.then(function(data) {
// And assemble an object structure of the original object
return Delivery.categorizeContent(data, categories);
})
.catch(console.error);
}
/*
* Helper methods section
*/
// Retrun array of promises with objects obtained from the Kentico Kontent storage
static getRawData(options) {
return Promise.map(options, (item) => {
return requestPromise(item).catch(console.error);
});
}
// Return url that should be requested
static getDeliveryUrl(projectID, isPreview) {
let url = '';
// If we want to preview our content we need request a slightly different url
if (isPreview) {
url = 'https://preview-deliver.kontent.ai/' + projectID + '/items';
} else {
url = 'https://deliver.kontent.ai/' + projectID + '/items';
}
return url;
}
// Returns options for the request
// Structure of the options object is defined by the request-promise package (https://www.npmjs.com/package/request-promise)
static getOptions(params, projectID, previewKey, isPreview) {
var options = [];
// Create request options of each param
if (isPreview && previewKey !== null) {
params.forEach((item) => {
options.push({
uri: Delivery.getDeliveryUrl(projectID, isPreview) + item,
json: true,
simple: false,
headers: {
Authorization: 'Bearer ' + previewKey
}
});
});
} else {
params.forEach((item) => {
options.push({
uri: Delivery.getDeliveryUrl(projectID, isPreview) + item,
json: true,
simple: false
});
});
}
return options;
}
// Join array of category names and array of responses to fit the original object structure
static categorizeContent(content, categories) {
let categorizedContent = {};
content.forEach((item, index) => {
categorizedContent[categories[index]] = item;
});
return categorizedContent;
}
};
/*
* Usage
*/
// Initialize Delivery with Project ID and Preview API Key
let kenticoKontentProject = new Delivery('2548121d-cad8-4458-a910-5e4b54cb0956', 'ew0KICAiYWxnIjogIkhTMjU2IiwNCiAgInR5cCI6ICJKV1QiDQp9.ew0KICAidWlkIjogInVzcl8wdlVJVzkwTnRQSVNxNm1GSDN2ZFhiIiwNCiAgImVtYWlsIjogImhlbGxvQG1pbGFubHVuZC5jb20iLA0KICAicHJvamVjdF9pZCI6ICIyNTQ4MTIxZC1jYWQ4LTQ0NTgtYTkxMC01ZTRiNTRjYjA5NTYiLA0KICAianRpIjogInhrU1BLUjlzbzgxSV9rel8iLA0KICAidmVyIjogIjEuMC4wIiwNCiAgImdpdmVuX25hbWUiOiAiTWlsYW4iLA0KICAiZmFtaWx5X25hbWUiOiAiTHVuZCIsDQogICJhdWQiOiAicHJldmlldy5kZWxpdmVyLmtlbnRpY29jbG91ZC5jb20iDQp9.PpBh6wTk57e1_tPHzROiqWPTpr3IjrEoGN8J4rtfPIg');
// Request the Kentico Kontent storage with filtering url parameters and a boolean flag defining whether you want preview content or not
kenticoKontentProject.getContent({
master: '?system.type=master',
page: '?system.type=home'
}, true)
.then(console.log) // Show results
.catch(console.error); // Or error
Further reading
all posts- Kentico Xperience
Safe attachment URLs resolution in srcset attribute in Page Builder in Kentico Xperience
In this post, I will provide you with a quick tip on how to fix the attachment URLs resolution in srcset attribute in Page Builder in Kentico Xperience.
- Front-end & JavaScript
Simple cookie bar
EU cookie legislation requires website owners to inform visitors about the use of cookies. In this article, I will provide you with a simple solution of an informative cookie bar.
- Front-end & JavaScript
Simple scroll parallax
Recently, a designer asked me to add a parallax background image on a website. I researched the web to find a suitable solution. Regrettably, I found only massive libraries that wo…