Mock up SharePoint Rest API using NodeJS and ExpressJS - node.js

I'm trying to create a development environment for a small sharepoint application. The application queries a couple of Sharepoint 2013 lists and builds a custom view of the data. Rather than publishing to sharepoint every time I make a change I would like to use NodeJS and Express 4 to mock up the api. I don't need to mock up any of other CRUD activities; just the GET requests.
I started out using the following:
const express = require('express')
const fs = require('fs');
const path = require('path');
const csv = require('csvtojson');
const app = express();
function openAndSend(file, res){
csv().fromFile(path.join(__dirname,file))
.then(jsonarray)=>{
res.setHeader('Content-Type','application/json');
res.send({d:{results:jsonarray}});
});
}
app.get('/dataset',(req,res)=>{
openAndSend('./data/dataset.csv', res);
});
app.get('/people',(req,res)=>{
openAndSet('./data/people.csv', res);
});
How can I use express js to mock up something like
/api/lists/getbytitle("Data Set")/items and /api/lists/getbytitle("People")/items
I tried changing the app.get functions to app.get('/api/lists/getbytitle("Data%20Set")/items', ....); which did not work. However removing get getbytitle("...")" routed correctly.

I was able to solve the issue using express Router and a regex expression for the path/route. The most challenging part was discovering that special characters needed to be encoded.
var router = express.Router();
router.get(/getbytitle\((%22|')Data%20Set(%22|')\)\/items\/?$/i,(req,res,next)=>{
openAndSend('./data/dataset.csv', res);
});
router.get(/getbytitle\((%22|')people(%22|')\)\/items\/?$/i,(req,res,next)=>{
openAndSend('./data/people.csv', res);
});
app.use('/_api/lists',router);

Related

GET POST requests in node js

Hi friends I'm new in MERN application build I want to know that How we can handle requests in nodeJs and connect mongoose to the database. Please help me out.
I would recommend the library Express.js, but you could also use another one if you want to.
Here's an example for how this could look like in Express:
const express = require('express');
const app = express();
app.use(express.json()); // necessary for req.body
app.post('login', function(req, res){
let data = req.body;
// do something..
res.sendStatus(200);
});

How to customise get method with different queries in Express.js with Node.js?

I'm currently building a REST API using Node.js with Express.js and I'm quite new to this technology. The following code shows the get method to a list of councils stored in MongoDB.
const { Council } = require('../mongoose-models/council');
const express = require('express');
const router = express.Router();
router.get('/', async (req, res) => {
const query = req.query;
const councilsList = await Council.find(query);
if (!councilsList) return res.status(404).send('No councils found.');
res.send(councilsList);
});
module.exports = router;
From my previous experience when developing REST API using java, I can customise different queries by implementing different methods with their own paths. For example:
#Path("findByCouncilName/{councilName}")
#Path("findCouncilsNotInMyArea/{longitude}/{latitude}")
And within each method, I can then write different logics. However, in Express.js, it seems that I have to implement all these different logics into one block. It seems not flexible and how can actually implement it? Furthermore, does the query must be same as the key name in MongoDB? What if I want to filter the results based on a specified index element in a nested array in a document?
For your routes:
#Path("findByCouncilName/{councilName}")
#Path("findCouncilsNotInMyArea/{longitude}/{latitude}")
If you are to implement them in express, you can split them into different blocks actually.
Instead of listening to '/' and try to handle everything inside, you can try this.
const express = require('express');
const router = express.Router();
router.get('/findByCouncilName/:councilName', async (req, res) => {
const councilName = req.params.councilName;
// Your logic goes here
res.send();
});
router.get('/findCouncilsNotInMyArea/:longitude/:latitude', async (req, res) => {
const longitude = req.params.longitude;
const latitude = req.params.latitude;
// Your logic goes here
res.send();
});
module.exports = router;
You can use it like lets say:
router.get('/:councilName', async (req, res) => {
Then use the parameter in the route with :
req.params.councilName
Express doc is your friend
https://expressjs.com/en/guide/routing.html
Here is everything you should know about express routing.
You can specify individual logic for every pat-method pair, and again, use general as needed.
You need to be aware of path order in which Express resolves them, eg. first path to match will will be executed.

Express API Versioning with query params

I'm a NodeJS beginner and I'm developing an API backend using Express.
I have read many articles about how to do API versioning with Express but none of them explains how to use the query params approach.
I like doing API versioning like:
example.org/users?version=1.0
example.org/users?version=1.1
example.org/users?version=1.2
Etc. How can properly handle and structure my API code to achieve this?
You can do something like that (this is just an example, you can play arround with it in many ways)
index.js:
var express= require('express')
, app = express()
, usersHandlers = require('./handlers/users');
app.use("/users",usersHandler);
function usersHandler(req,res){
var version = req.query.version;
console.log("This code is relevent for all versions");
usersHandlers[version](req,res);
}
app.listen(8000,function(){
console.log('Server running at http://127.0.0.1:8000/');
});
users.js:
module.exports = {
'1.0' : function(req,res){
res.send("This is the response for version 1.0");
},
'2.0' : function(req,res){
res.send("This is the response for version 2.0");
}
}

Manually injecting express app via `http.createServer` proxy

I am currently authoring a component for a users sites which adds a number of resources to their server. For my part, I am wanting to use express, but the user could be using express themselves or some other web framework.
Because I want this to just work out of the box, I was attempting to setup my express pipeline via proxying http.createServer. Injecting the pipeline this way seems to work reasonably well in cases where I handle the request, but it fails in cases where I let it fall through and execute the users callback (specifically, it says that the response headers have been sent already).
Here is the sample I am working on. Any ideas?
var http = require('http');
var express = require('express');
var setupProxy = function setupProxy() {
var app = buildApp();
var oldCreateServer = http.createServer;
http.createServer = function(callback) {
return oldCreateServer(function(req, res) {n
app.apply(this, arguments);
if (!res.finished) {
callback.apply(this, arguments);
}
});
};
};
var buildApp = function buildApp() {
var app = express();
app.use('/test', function(req, res) {
res.send('Hello World');
});
return app;
};
I suspect your express handling creates a default 404 response when it doesn't match any of your routes. So, that would be the cause of the headers already sent issue when you are not handling it, but trying to pass it on.
So, I think you need your own 404 handler that writes nothing to the request (e.g. does nothing), but keeps Express from handling it.
Or, another possibility would be to call the user's server callback from your express 404 handler and not elsewhere.

Mount Koajs app on top of Express

From koajs.com:
app.callback()
Return a callback function suitable for the http.createServer() method to handle a request. You may also use this callback function to mount your koa app in a Connect/Express app.
Now I have an Express app that already starts its own http server. How can I mount a koa app on top of this existing server, so that it shares the same port?
Would I include the koa app as an Express middlware? Do I still use app.callback() for that?
expressapp.use(koaapp.callback()) is fine. but remember, koaapp.callback() does not have a next, so there's no passing errors to the express app or skipping the koaapp once you use it.
it's better to keep them completely separate since their APIs are incompatible
var koaapp = koa()
var expressapp = express()
http.createServer(req, res) {
if (true) koaapp(req, res);
else expressapp(req, res);
})
Since you need a server instance in order to mount a middleware on a specific /prefix, it would be something like
var http = require('http');
var expressApp = require('express');
var koaApp = require('koa');
// ...
expressApp.use('/prefix', http.createServer(koaApp.callback()));

Resources