diff --git a/sample-proxies/pagination/README.md b/sample-proxies/pagination/README.md new file mode 100644 index 00000000..f784581e --- /dev/null +++ b/sample-proxies/pagination/README.md @@ -0,0 +1,81 @@ +# API Pagination + +This sample shows how to perform a simple "Pagination of data" using javascript policy. + +It caches the offset and limit based on user_id header and based on that it paginates. + +It uses these policies: + +CacheLimit.xml - It caches the Limit value +CacheOffset.xml - It caches the offset value +CacheResponse.xml - Response Cache +ContentListings.xml - Policy that mocks up 100 book entries +GetPaginationParams.xml - This policy extracts query parameters. +LookupLimit.xml - Looks up the cache to get the cached Limit +LookupOffset.xml - This looks up the offset value +Pagination.xml - This is the javascript policy to paginate the data. + + +#Explaination +You have to set two headers: + +user_id : this is used to store the pagination configuration(offset and limit) into cache by user_id. +bypass-cache: TRUE value means ignore cache, FALSE value means lookup for a response in cache. This value is affecting just the response cache policy. + +Ex: + +request.header.user_id = tester1 +request.header.bypass-cache = true + +Once you set the pagination configuration by user_id, the queryparams are not needed anymore, however you must provide a user_id to retrieve the pagination configuration and the next page. Once you reach the last page, the next request will retrieve the first page. + + +Complete example: + +First request (first page and pagination configuration): +curl -H "user_id: tester1" -H "bypass-cache: true" http://${host}/v1/demo/content-listing?offset=0&limit=10 + +This will return the first 10 entries. + +Second and further requests (next page or first page after you reach the last page): + +curl -H "user_id: tester1" -H "bypass-cache: false" http://${host}/v1/demo/content-listing + +This will return the next 10 entries. + +You can start over the pagination process by providing new pagination configuration (offset and limit queryparams). + + +# Set up + +* The username and password that you use to login to enterprise.apigee.com. +* The name of the organization in which you have an account. Login to + enterprise.apigee.com and check account settings. + +# Configure + +Update `/setup/setenv.sh` with your environment details + +# Import and deploy sample project + +To deploy, run `$ sh deploy.sh` + +To test, run `$ sh invoke.sh` + +# Get help + +For assistance, post to the [Apigee Developer Forum](http://support.apigee.com) + +Copyright © 2013 Apigee Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy +of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/sample-proxies/pagination/apiproxy/.DS_Store b/sample-proxies/pagination/apiproxy/.DS_Store new file mode 100644 index 00000000..d5745d79 Binary files /dev/null and b/sample-proxies/pagination/apiproxy/.DS_Store differ diff --git a/sample-proxies/pagination/apiproxy/Pagination.xml b/sample-proxies/pagination/apiproxy/Pagination.xml new file mode 100755 index 00000000..28f6b918 --- /dev/null +++ b/sample-proxies/pagination/apiproxy/Pagination.xml @@ -0,0 +1,29 @@ + + + + 1379217095696 + jcastillo@apigee.com + Content Listing + DirectTVDemo + 1379217095696 + jcastillo@apigee.com + + CacheLimit + CacheOffset + CacheResponse + ContentListings + GetPaginationParams + LookupLimit + LookupOffset + Pagination + + + default + + + jsc://paginate.js + java://DirectTVContentListings.jar + + + + diff --git a/sample-proxies/pagination/apiproxy/policies/CacheLimit.xml b/sample-proxies/pagination/apiproxy/policies/CacheLimit.xml new file mode 100755 index 00000000..33375e39 --- /dev/null +++ b/sample-proxies/pagination/apiproxy/policies/CacheLimit.xml @@ -0,0 +1,18 @@ + + + CacheLimit + + + + ContentListings + Pagination + Limit + + + PaginationCache + Exclusive + + 1800 + + limit + diff --git a/sample-proxies/pagination/apiproxy/policies/CacheOffset.xml b/sample-proxies/pagination/apiproxy/policies/CacheOffset.xml new file mode 100755 index 00000000..93b72ba2 --- /dev/null +++ b/sample-proxies/pagination/apiproxy/policies/CacheOffset.xml @@ -0,0 +1,18 @@ + + + CacheOffset + + + + ContentListings + Pagination + Offset + + + PaginationCache + Exclusive + + 1800 + + offset + diff --git a/sample-proxies/pagination/apiproxy/policies/CacheResponse.xml b/sample-proxies/pagination/apiproxy/policies/CacheResponse.xml new file mode 100755 index 00000000..1b7c75b4 --- /dev/null +++ b/sample-proxies/pagination/apiproxy/policies/CacheResponse.xml @@ -0,0 +1,19 @@ + + + CacheResponse + + + + ContentListings + Response + + PaginationCache + Exclusive + + + + 1800 + + request.header.bypass-cache = "true" + + diff --git a/sample-proxies/pagination/apiproxy/policies/ContentListings.xml b/sample-proxies/pagination/apiproxy/policies/ContentListings.xml new file mode 100755 index 00000000..d68f97d8 --- /dev/null +++ b/sample-proxies/pagination/apiproxy/policies/ContentListings.xml @@ -0,0 +1,7 @@ + + + ContentListings + + + jsc://contentlisting.js + diff --git a/sample-proxies/pagination/apiproxy/policies/GetPaginationParams.xml b/sample-proxies/pagination/apiproxy/policies/GetPaginationParams.xml new file mode 100755 index 00000000..59366db8 --- /dev/null +++ b/sample-proxies/pagination/apiproxy/policies/GetPaginationParams.xml @@ -0,0 +1,16 @@ + + + GetPaginationParams + + + + {limit} + + + {offset} + + + {dir} + + true + diff --git a/sample-proxies/pagination/apiproxy/policies/LookupLimit.xml b/sample-proxies/pagination/apiproxy/policies/LookupLimit.xml new file mode 100755 index 00000000..5bd417a9 --- /dev/null +++ b/sample-proxies/pagination/apiproxy/policies/LookupLimit.xml @@ -0,0 +1,15 @@ + + + LookupLimit + + + + ContentListings + Pagination + Limit + + + PaginationCache + Exclusive + limit + diff --git a/sample-proxies/pagination/apiproxy/policies/LookupOffset.xml b/sample-proxies/pagination/apiproxy/policies/LookupOffset.xml new file mode 100755 index 00000000..9ca1de23 --- /dev/null +++ b/sample-proxies/pagination/apiproxy/policies/LookupOffset.xml @@ -0,0 +1,15 @@ + + + LookupOffset + + + + ContentListings + Pagination + Offset + + + PaginationCache + Exclusive + offset + diff --git a/sample-proxies/pagination/apiproxy/policies/Pagination.xml b/sample-proxies/pagination/apiproxy/policies/Pagination.xml new file mode 100755 index 00000000..1651254f --- /dev/null +++ b/sample-proxies/pagination/apiproxy/policies/Pagination.xml @@ -0,0 +1,7 @@ + + + Pagination + + + jsc://paginate.js + diff --git a/sample-proxies/pagination/apiproxy/proxies/default.xml b/sample-proxies/pagination/apiproxy/proxies/default.xml new file mode 100755 index 00000000..adce39b6 --- /dev/null +++ b/sample-proxies/pagination/apiproxy/proxies/default.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + GetPaginationParams + + + + CacheResponse + + + request.queryparam.offset = null or request.queryparam.offset = \"\" + + LookupOffset + + + request.queryparam.limit = null or request.queryparam.limit = \"\" + + LookupLimit + + + + + + ContentListings + + + + CacheResponse + + + + Pagination + + + + CacheOffset + + + + CacheLimit + + + (proxy.pathsuffix MatchesPath "/content-listing") and (request.verb = "GET") + + + + + + + + + + + + /v1/paginate + + default + secure + + + diff --git a/sample-proxies/pagination/apiproxy/resources/jsc/contentlisting.js b/sample-proxies/pagination/apiproxy/resources/jsc/contentlisting.js new file mode 100644 index 00000000..c921c3ec --- /dev/null +++ b/sample-proxies/pagination/apiproxy/resources/jsc/contentlisting.js @@ -0,0 +1,18 @@ +var books = { + book: [] +}; + + +for (var i=0 ; i < 100 ; i++) { + +books.book.push({ + "id" : i, + "title" : "book title " + i, + "author" : "book author " + i, + "comments" : "book comments " + i +}); + +} + +context.setVariable("response.content", JSON.stringify(books)); + diff --git a/sample-proxies/pagination/apiproxy/resources/jsc/paginate.js b/sample-proxies/pagination/apiproxy/resources/jsc/paginate.js new file mode 100755 index 00000000..6b037d81 --- /dev/null +++ b/sample-proxies/pagination/apiproxy/resources/jsc/paginate.js @@ -0,0 +1,24 @@ +var contentListingsJSON = JSON.parse(context.proxyResponse.content); +var listingsLength = contentListingsJSON.book.length; +var offset = +context.getVariable("offset"); +var limit = +context.getVariable("limit"); +var temp = offset; +var offset_plus_limit = offset+limit; +context.setVariable("offset_plus_limit", offset_plus_limit); +var contentBriefPage = new Array(); +while(temp < listingsLength) { + if(temp >= offset && temp < offset_plus_limit) { + contentBriefPage.push(contentListingsJSON.book[temp]); + } else if(temp >= offset+limit){ + break; + } + temp++; +} +if(temp < offset_plus_limit || temp == listingsLength) { + context.setVariable("offset", 0); +} else { + context.setVariable("offset", temp); +} +contentListingsJSON.book = contentBriefPage; +context.proxyResponse.content = JSON.stringify(contentListingsJSON); +context.proxyResponse.headers["Content-Type"] = "application/json"; \ No newline at end of file diff --git a/sample-proxies/pagination/deploy.sh b/sample-proxies/pagination/deploy.sh new file mode 100755 index 00000000..ecb7760a --- /dev/null +++ b/sample-proxies/pagination/deploy.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +source ../../setup/setenv.sh + +echo "Enter your password for the Apigee Enterprise organization $org, followed by [ENTER]:" + +read -s password + +echo Creating cache + +curl -X POST -H "Content-type:text/xml" -d @paginate-cache.xml https://api.enterprise.apigee.com/v1/o/$org/environments/$env/caches -u $username:$password + + +echo Deploying $proxy to $env on $url using $username and $org + +../../tools/deploy.py -n pagination -u $username:$password -o $org -h $url -e $env -p / -d ../pagination + +echo "If 'State: deployed', then your API Proxy is ready to be invoked." + +echo "Run 'invoke.sh'" diff --git a/sample-proxies/pagination/invoke.sh b/sample-proxies/pagination/invoke.sh new file mode 100755 index 00000000..3798c4b9 --- /dev/null +++ b/sample-proxies/pagination/invoke.sh @@ -0,0 +1,18 @@ + v#!/bin/bash + +echo Using org and environment configured in /setup/setenv.sh + +source ../../setup/setenv.sh + +echo "Enter your password for the Apigee Enterprise organization, followed by [ENTER]:" + +read -s password + +set -x + +curl -H "user_id : tester1" -H "bypass-cache : true" "http://$org-$env.apigee.net/v1/paginate/content-listing?offset=0&limit=20" + +echo Now use without query parameter + +curl -H "user_id : tester1" -H "bypass-cache : false" "http://$org-$env.apigee.net/v1/paginate/content-listing" + diff --git a/sample-proxies/pagination/paginate-cache.xml b/sample-proxies/pagination/paginate-cache.xml new file mode 100644 index 00000000..b9a3db0e --- /dev/null +++ b/sample-proxies/pagination/paginate-cache.xml @@ -0,0 +1,16 @@ + + + + 300 + + + 1024 + + A Cache resource for the test environment. + 0 + 0 + 100 + 0 + false + false + diff --git a/sample-proxies/pagination/populate_cache.sh b/sample-proxies/pagination/populate_cache.sh new file mode 100755 index 00000000..2b34a9f2 --- /dev/null +++ b/sample-proxies/pagination/populate_cache.sh @@ -0,0 +1,10 @@ +#!/bin/bash + + +source ../../setup/setenv.sh +echo "Enter your password for the Apigee Enterprise organization $org, followed by [ENTER]:" + +read -s password + +curl -H "Content-type:text/xml" -X POST -d @paginate-cache.xml https://api.enterprise.apigee.com/v1/o/${org}/environments/${env}/caches \ + -u ${username}:${password}