Hello,
What @HodyCrouch said is correct, and the reason for that github project was to find a solution to build your own front-end application using the Meraki API.
I wrote this app to act as a basic starter project and avoid some of the initial challenges I had getting started. I'm working towards a better demo app, but the server/client communication was this focus for this project.
https://github.com/dexterlabora/meraki-dashboard-api-express
The NodeJS w/ Express app serves a web page and provides an API proxy to Meraki.
The web page (index.html ) calls '/api/' as the root URL, which the Node server.js handles.
The Node server will then apply any additional headers, parse the data and make the API request.
So instead of calling the Meraki API directly from the browser, the page would call the local server.
https://api.meraki.com/api/v0/organizations --> http://localhost:8085/api/organizations
Additionally, aspecial wrapper for making requests, request-meraki.js , is used to handle multiple redirects in the API call from https://api.meraki.com to the organization's shard, https://n123.meraki.com/
More info on the app inner workings:
The sample code was updated to demonstrate a post by creating a new network.
Client-Side (create a network by posting data)
createNetwork (orgId, data) {
axios.post('/api/organizations/'+orgId+'/networks', data )
.then(response => {
console.log('createNetwork response', response.data);
this.merakiData = response.data;
})
.catch(e => {
this.errors.push(e)
})
},
Server Side
// API Route - Will be proxied through Meraki Dashboard API
app.use('/api', jsonParser, function (req, res){
// Use client supplied API key or default to server config.
var apiKey = '';
if('x-cisco-meraki-api-key' in req.headers){
apiKey = req.headers['x-cisco-meraki-api-key'];
console.log("New headers sent", apiKey );
}else{
apiKey = configs.apiKey;
}
var options = {
qs: req.query,
url: configs.apiUrl + req.url,
method: req.method,
body: JSON.stringify(req.body),
//followAllRedirects: true, // Does not work as intended with PUT,POST,DELETE (returns a [GET] on final location)
headers: {
'X-Cisco-Meraki-API-Key': apiKey,
'Content-Type': 'application/json'
}
}
requestMeraki(options, function(err, response, data){
if(err){
console.log("requestMeraki err ", err)
res.status(response.statusCode).send({
message: 'err'
});
res.send(err);
}
console.log('FINAL res.statusCode ',response.statusCode);
console.log('FINAL res.body ',response.body);
res.setHeader('content-type', response.headers['content-type']);
res.status(response.statusCode).send(data);
});
});
request-meraki.js
// Handles Meraki API requests. Has additional logic to follow the HTTP redirects properly.
var request = require('request');
var JSONbig = require('json-bigint')({"storeAsString": true});
// Recursive function to follow Meraki API redirects
var requestMeraki = function (options, callback){
request(options, function(error, res, data) {
if (error) {
return callback(error);
} else {
if ((res.statusCode == '308' || '307' || '302' || '301') && res.headers.location){
//console.log('REDIRECT: (recursive function)')
options.url = res.headers.location;
return requestMeraki(options, function(err, res, data){return callback(err, res, data)});
}else{
// parse the large integers properly if data exists
try {
var parsedData = JSONbig.parse(data);
return callback(error, res, parsedData);
} catch (e) {
console.log('error: no data returned ',error)
}
//console.log("FINISHED")
return callback(error, res, data);
}
}
});
}
module.exports = requestMeraki;