How to use Caml Query in SharePoint Rest API using Express JS and Typescript

Krishna KV
 
Team Leader, Aspire Systems
June 24, 2017
 
Rate this article
 
Views
4903

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)

clip_image002

Open the browser and navigate to http://localhost:2001/customers to access the API

Author Info

Krishna KV
 
Team Leader, Aspire Systems
 
Rate this article
 
Krishna K.V has been working in IT Industry for over 7+ years. He holds a Master Degree in Information Technology. He is more interested to learn and share new technologies, ...read more
 

Leave a comment