In the article we can look into how to write and configure Express JS using Typescript and passing the Caml Query in SharePoint Rest API
Prerequisite
· Node JS
· Visual Studio Code
pacakage.json
{
"name": "ejssp",
"version": "1.0.0",
"description": "Express",
"scripts": {
"start": "tsc -p ./src && concurrently "tsc -w -p ./src" "nodemon build/server/main.js""
},
"keywords": [
"typescript"
],
"dependencies": {
"@types/express": "^4.0.32",
"@types/body-parser": "^0.0.32",
"@types/node": "^6.0.48",
"agentkeepalive": "3.1.0",
"async": "2.1.5",
"body-parser": "^1.17.1",
"express": "^4.15.2",
"express-ntlm": "2.1.5",
"httpntlm": "1.7.5",
"ts-loader": "2.0.1",
"ts-node": "1.2.1",
"tslint": "^4.0.0",
"typescript": "^2.1.6"
},
"devDependencies": {
"concurrently": "^3.1.0",
"nodemon": "^1.11.0"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "es6",
"module": "commonjs"
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules"
]
}
Add a folder src and add the following files.
tsconfig.json
{
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es6", "dom"],
"mapRoot": "../build/server",
"module": "commonjs",
"moduleResolution": "node",
"outDir": "../build/server",
"sourceMap": true,
"target": "es6",
"typeRoots": [
"../node_modules/@types"
]
}
}
customer.ts
import { Router, Request, Response, NextFunction } from 'express';
let httpntlm = require('httpntlm');
let ntlm = require('httpntlm').ntlm;
let async = require('async');
let httpreq = require('httpreq');
let HttpsAgent = require('agentkeepalive').HttpsAgent;
let keepaliveAgent = new HttpsAgent();
export class Customer {
public static route: string = '/customers';
public router: Router = Router();
constructor() {
this.router.get('/', this.getCustomers);
}
private static getSPConfig() {
return {
url: 'https://url-of-the-sp-site/',
username: '[User Name]',
password: '[Password]',
domain: '[Domain Name]',
workstation: '',
headers: {
'Accept': 'application/json;odata=verbose',
'content-type': 'application/json;odata=verbose;'
}
};
}
private static getDigest(returnfun) {
let spConfig = Customer.getSPConfig();
async.waterfall([
function (callback) {
let type1msg = ntlm.createType1Message(spConfig);
httpreq.post(spConfig.url + '_api/contextinfo', {
headers: {
'Connection': 'keep-alive',
'Authorization': type1msg,
'accept': 'application/json;odata=verbose'
},
agent: keepaliveAgent
}, callback);
},
function (res, callback) {
if (!res.headers['www-authenticate']) {
return callback(new Error('www-authenticate not found on response of second request'));
}
let type2msg = ntlm.parseType2Message(res.headers['www-authenticate']);
let type3msg = ntlm.createType3Message(type2msg, spConfig);
setImmediate(function () {
httpreq.post(spConfig.url + '_api/contextinfo', {
headers: {
'Connection': 'Close',
'Authorization': type3msg,
'accept': 'application/json;odata=verbose'
},
allowRedirects: false,
agent: keepaliveAgent
}, callback);
});
}
], function (err, response) {
if (err) {
console.log(err);
}
let json = JSON.parse(response.body);
return returnfun(json);
});
}
private getCustomers(req: Request, res: Response, next: NextFunction) {
let opt = Customer.getSPConfig();
let id =20;
let listName = "Testing";
let viewXml = {
ViewXml: '<View>' +
'<Query>' +
'<Where><Gt>' +
'<FieldRef Name='ID' />' +
'<Value Type='Number'>' + id + '</Value>' +
'</Gt></Where>' +
'</Query>' +
'<ViewFields>' +
'<FieldRef Name="Title" />' +
'<FieldRef Name="Id" />' +
'</ViewFields>' +
'</View>'
};
opt.url = opt.url + '_api/web/lists/getByTitle('' + listName + '')/GetItems(query=@v1)?' +
'@v1=' + JSON.stringify(viewXml);
Customer.getDigest(json => {
console.log('json');
opt.headers['X-RequestDigest'] = json.d.GetContextWebInformation.FormDigestValue;
let customers = [{ customerId: 1001, customerName: 'suresh' }, { customerId: 1001, customerName: 'suresh' }]
httpntlm.post(opt, (error, response) => {
if (error) {
res.status(500).send(error);
}
else {
let testingData = JSON.parse(response.body).d.results;
let jsonData = [];
testingData.forEach(element => {
jsonData.push({
Id:element['Id'],
Title:element['Title']
});
});
res.status(200).send(jsonData);
}
});
});
}
}
While using the Caml query in SharePoint API, the post method is used to retrieve the list item.
main.ts
import { Router, Express } from 'express';
import * as express from 'express';
import * as http from 'http';
import { json, urlencoded } from 'body-parser';
import { Customer } from './customer';
export class Main {
private port: number = 2001;
constructor() {
let app = express();
this.configure(app);
}
private configure(app) {
app.use(json());
app.use(urlencoded({ extended: true }));
app.use(Customer.route, new Customer().router)
let server = http.createServer(app);
server.listen(this.port);
console.log('server started at ' + this.port);
}
}
new Main()
To run the API.
Open command prompt
Type npm install (install the node packages) and followed by npm start (to start the api)
Open the browser and navigate to http://localhost:2001/customers to access the API
Leave a comment