This article explain a solution to a scenario, where our back end service is not supporting a pagination and responds with a large xml and our client expects an API which need to support pagination.
The flow diagram below summarizes the task we are going to achieve.
The API I have created for this sample as below:
<api xmlns="http://ws.apache.org/ns/synapse" name="PaginationAPI" context="/listStudents">
<resource methods="GET" uri-template="/getPaginatedStudentsList?start={start}&count={count}" protocol="http">
<inSequence>
<log level="custom">
<property name="STATUS" value="PaginationAPI Invoked..."/>
<property name="start" expression="$ctx:query.param.start"/>
<property name="count" expression="$ctx:query.param.count"/>
</log>
<script language="js">var count = parseInt(mc.getProperty('query.param.count')); var start = parseInt(mc.getProperty('query.param.start')); var startIndex = parseInt(start); var endIndex = parseInt(start) + parseInt(count) + 1; mc.setProperty('startIndex', startIndex); mc.setProperty('endIndex', endIndex);</script>
<call>
<endpoint>
<http method="GET" uri-template="http://www.mocky.io/v2/5be818f7300000750058c312"/>
</endpoint>
</call>
<log level="full" description="before xslt transformation"/>
<xslt key="gov:/pagination-test.xslt">
<property name="startIndex" expression="$ctx:startIndex"/>
<property name="endIndex" expression="$ctx:endIndex"/>
</xslt>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
The back end service has been created in mocky.io and the sample data response from it will be as below:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<students>
<school>St.Michael's College, Batticaloa</school>
<address>Batticaloa, Srilanka</address>
<student>
<recno>1</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student>
<recno>2</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1
</address>
<age>27</age>
</student>
<student>
<recno>3</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student>
<recno>4</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student>
<recno>5</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student>
<recno>6</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student>
<recno>7</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student>
<recno>8</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student>
<recno>9</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student>
<recno>10</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student>
<recno>11</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student>
<recno>12</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
</students>
</soapenv:Body>
</soapenv:Envelope>
Then the XSLT will be as below:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="startIndex"></xsl:param>
<xsl:param name="endIndex"></xsl:param>
<xsl:template match="/">
<students>
<xsl:apply-templates select="//students/student[position() > $startIndex and position() < $endIndex]"/>
</students>
</xsl:template>
<xsl:template match="//students/student[position() > $startIndex and position() < $endIndex]">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
Below are the test results:
1) When calling the API with URL: http://172.17.0.1:8280/listStudents/getPaginatedStudentsList?start=0&count=20
<students>
<student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<recno>1</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<recno>2</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1
</address>
<age>27</age>
</student>
<student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<recno>3</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<recno>4</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<recno>5</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<recno>6</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<recno>7</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<recno>8</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<recno>9</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<recno>10</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<recno>11</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<recno>12</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
</students>
2) When calling the API with URL: http://172.17.0.1:8280/listStudents/getPaginatedStudentsList?start=5&count=3
<students>
<student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<recno>6</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<recno>7</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
<student xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<recno>8</recno>
<name>NTest1</name>
<surname>STest1</surname>
<address>ATest1</address>
<age>27</age>
</student>
</students>
That's it... and hope this helps someone implementing a pagination scenario.