All Projects → spreadshirt → continuation-token

spreadshirt / continuation-token

Licence: MIT license
A library for fast, reliable and stateless Web API pagination with Continuation Tokens.

Programming Languages

kotlin
9241 projects
java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to continuation-token

Nopaginate
Android pagination library (updated 01.05.2018)
Stars: ✭ 180 (+958.82%)
Mutual labels:  pagination
Instagram Proxy Api
CORS compliant API to access Instagram's public data
Stars: ✭ 245 (+1341.18%)
Mutual labels:  pagination
materialui-pagination
A simple pagination component for Material UI.
Stars: ✭ 31 (+82.35%)
Mutual labels:  pagination
Rummage ecto
Search, Sort and Pagination for ecto queries
Stars: ✭ 190 (+1017.65%)
Mutual labels:  pagination
Sqlhelper
SQL Tools ( Dialect, Pagination, DDL dump, UrlParser, SqlStatementParser, WallFilter, BatchExecutor for Test) based Java. it is easy to integration into any ORM frameworks
Stars: ✭ 242 (+1323.53%)
Mutual labels:  pagination
flask-rest-paginate
Pagination Extension for flask-restful
Stars: ✭ 18 (+5.88%)
Mutual labels:  pagination
Advancedlist
Advanced List View for SwiftUI with pagination & different states
Stars: ✭ 165 (+870.59%)
Mutual labels:  pagination
repository
[PHP 7] Implementation and definition of a base Repository in Domain land.
Stars: ✭ 26 (+52.94%)
Mutual labels:  pagination
Gatsby Starter Business
Gatsby Business Website Starter
Stars: ✭ 243 (+1329.41%)
Mutual labels:  pagination
blogging-app-with-Angular-CloudFirestore
A blogging application created with the help of Angular on front-end and Google Cloud Firestore on backend.
Stars: ✭ 45 (+164.71%)
Mutual labels:  pagination
Jquerydatatablesserverside
Asp.Net Core Server Side for Jquery DataTables Multiple Column Filtering and Sorting with Pagination and Excel Export
Stars: ✭ 191 (+1023.53%)
Mutual labels:  pagination
V Selectpage
SelectPage for Vue2, list or table view of pagination, use tags for multiple selection, i18n and server side resources supports
Stars: ✭ 211 (+1141.18%)
Mutual labels:  pagination
vue-laypage
📃 A simple pagination component for Vue.js 2.x
Stars: ✭ 25 (+47.06%)
Mutual labels:  pagination
Vue Bootstrap4 Table
Advanced table based on Vue 2 and Bootstrap 4 ⚡️
Stars: ✭ 187 (+1000%)
Mutual labels:  pagination
beer-app
🍺 Example App - Paginate API response with BLoC in Flutter
Stars: ✭ 20 (+17.65%)
Mutual labels:  pagination
Pagerfanta
Pagination library for PHP applications with support for several data providers
Stars: ✭ 175 (+929.41%)
Mutual labels:  pagination
Tablefilter
A Javascript library making HTML tables filterable and a bit more :)
Stars: ✭ 248 (+1358.82%)
Mutual labels:  pagination
roove
Dating app based on firebase services and facebook login. MVVM-Kotlin-RxJava-Dagger-Databinding
Stars: ✭ 55 (+223.53%)
Mutual labels:  pagination
11r
America's favorite Eleventy blog template.
Stars: ✭ 135 (+694.12%)
Mutual labels:  pagination
Ajaxinate
🎡 Ajax pagination plugin for Shopify themes
Stars: ✭ 107 (+529.41%)
Mutual labels:  pagination

Continuation Token

Build Status

A library for fast, reliable and stateless Web API pagination with Continuation Tokens. It's written in Kotlin, but can be used for both Java and Kotlin services.

This Library is Deprecated

We don't recommend the Timestamp_Offset_Checksum approach - which in implemented in this library - any longer. Instead, we moved to the Timestamp_ID approach. It's even more reliable and so simple to implement that you don't need a library anymore.

The Approach

A detailed explanation of the approach and the used algorithm can be found in the blog post "Web API Pagination with Continuation Tokens". Some bullet points about continuation tokens are:

  • It's a keyset pagination approach.
  • The token is a pointer to a certain position within the list of all elements.
  • The token is passed to the client in the response body. The client can pass it back to the server as a query parameter in order to receive the next page.
  • The token has the format timestamp_offset_checksum.
  • The benefits:
    • It's fast because we don't need the expensive OFFSET clause.
    • It's reliable because we don't miss any elements and we can't end up in endless loops.
    • It's stateless. No state on the server-side is required. This way, we can easily load balance the requests over our multiple server instances.

Usage

Add the dependency:

<repositories>
    <repository>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
        <id>jcenter-releases</id>
        <name>jcenter</name>
        <url>http://jcenter.bintray.com</url>
    </repository>
</repositories>

<dependency>
    <groupId>com.spreadshirt</groupId>
    <artifactId>continuation-token</artifactId>
    <version>VERSION</version>
</dependency>

Check out the JCenter repository for the latest release.

Basically, we have to do the following things:

  1. Parse the continuation token with ContinuationTokenParser.toContinuationToken(). Mind the InvalidContinuationTokenException that can be thrown.
  2. Calculate a so called QueryAdvice based on a token (which can be null) and a pageSize. This can be done using Pagination.calculateQueryAdvice().
  3. Do the actual database query with a the data of the query advice and the library of your choice. But it's absolutely important to mind the following conditions in the query:
    • Use a "greater or equals" (>=) clause for the timestamp. The elements with exactly the timestamp are also required for the following step.
    • Order by both the timestamp and the id.
    • There have to be an index on both timestamp and the id.
  4. Pass the query result to Pagination.createPage(). It does the skipping, the checksum check and calculates the next continuation token. It finally returns the actual elements and the next token.

Kotlin:

val token = request.query("continuationToken")?.toContinuationToken()
val pageSize = request.query("pageSize")?.toInt() ?: 100
val queryAdvice = calculateQueryAdvice(token, pageSize)
val sql = """SELECT * FROM designs
    WHERE dateModified >= FROM_UNIXTIME(${queryAdvice.timestamp})
    ORDER BY dateModified asc, id asc
    LIMIT ${queryAdvice.limit};"""
val designs = template.query(sql, this::mapToDesign)
val nextPage = createPage(designs, token, pageSize)

//nextPage contains all relevant information which can now be mapped to the json response:
val entitiesOfThePage = nextPage.entities
val nextToken = nextPage.token
val doesNextPageExists = nextPage.hasNext

An more extensive and running example can be found in the Kotlin demo project. Check out the classes DesignResource and DesignDAO.

Java:

ContinuationToken token = ContinuationTokenParser.toContinuationToken(request.queryParams("continuationToken"));
int pageSize = request.queryParams("pageSize");
QueryAdvice queryAdvice = Pagination.calculateQueryAdvice(token, pageSize);
String sql = format("SELECT * FROM Employees" +
                             " WHERE UNIX_TIMESTAMP(timestamp) >= %d" +
                             " ORDER BY timestamp, id ASC" +
                             " LIMIT %d", queryAdvice.getTimestamp(), queryAdvice.getLimit())
List<Employee> entities = jdbcTemplate.query(sql, this::mapRow);
Page<Employee> page = Pagination.createPage(entities, token, pageSize);

//page contains all relevant information which can now be mapped to the json response:
List<Employee> entitiesOfThePage = page.getEntities();
ContinuationToken nextToken = page.getToken();
boolean doesNextPageExists = page.getHasNext();

Check out the Java demo project for a running example.

The algorithm ensures that you don't miss any element. However, you client may see the same element multiple times if it's changed during the pagination run.

Demos

Here you can find two example services that are implementing pagination with continuation tokens:

Repository Links

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].