Design for Server Side Pagination

In previous article, we have discussed about various type of pagination and that how these work. We have seen that in most of the scenarios, server side pagination is better than client side pagination. Client side pagination can be used only if data, i.e. the number of records, are limited. In that case, we can consider to load all data on client side and may divide the data in pages while showing on screen. However, if data is large, we would prefer the server side pagination.

In this article, we shall discuss how we can design the server side pagination component. At first, let us summarize the requirements for server side pagination.

Requirements
  • Data is large enough to support the needs of server side pagination implementation, as discussed in previous article.
  • Only current page of data (or may be 1-2 more pages) should be loaded from data repository (DB), so we want to reduce the need to load large amount of data from data repository. The same or lesser amount of data should be loaded on client side.
  • User can navigate  through the pages using next, previous, first or last page kind of actions. 
  • User can also perform 'sort' and 'search' kind of operation on the data.  
With above requirements, let us design the Pagination Component now. 

Analysis and HLD

After analysis of above requirements, following are the main design requirements:
  1. Client - Any software program which needs to retrieve the large amount of data, but want to present this to end user (or application) in pages. Client can be a UI which is showing listing of data to end user, or may be a command line tool to show the data. 
  2. We need a component which 
    1. Can maintain the state for each client. Various states needs to be maintained are: 
      1. Current Page for which data is returned last time to client
      2. Number of records to be returned for one page
      3. Various data retrieval attributes required for fetching the page data from Data Repository, using data access component. These can be 
        1. Criteria to select the desired data 
        2. Sort criteria
        3. Search criteria
        4. etc
    1. Can work as a channel to retrieve the data from repository using data access components
    2. Can provide utility methods to client for accessing the data pages based on user requests like, next | previous | first | last | specific page number
    3. Can provide methods to client using which client can change various data retrieval attributes. This is to support the scenario, when end user change the search or sort criteria at UI.
  1. We need an abstract data access layer (can call it pagination data provider), which can understand the  language of pages and can return the filtered, and sorted data for specified page. 
  2. This component can be named as 'Pagination Manager' 

A Tentative Flow of Control

With above design Perspective, a tentative flow will be: 
  • Any client which needs the Pagination services will access the Pagination Manager and will register itself with it by providing all data retrieval attributes, like data selection criteria, sorting and search criteria, data provider etc.
    • Data provider is something which only client has to provide, as only client knows that how data can be retrieved for its use. Alternatively, for specific scenario in application, a generic data provider can also be created which can return data by following generic data retrieval routine based on provided attributes.
  • Pagination Manager will register the client, will store it in cache and will assign a unique identity to it. 
  • This unique id will be returned to client, using which client can communication with Pagination Manager later for getting the data. 
  • Whenever client need any specific page of data, it will communicate with Pagination Manager by specifying its ID and will ask for the specific page. 
  • Pagination Manager will calculate the data range for given page, and will ask Data provider to provide that data by specifying the data range, and all attributes provided by client for data access. 
  • Data Provider will access the data repository and will return the data.
  • Pagination Manager will pack this data in a standard data structure (a DTO) and will return this to client.
  • Client may interact with Pagination Manager to change the data retrieval attributes. Pagination Manager will update its cache information to store it. The updated information will be used in next data retrieval request.  

Class Design 

Various class can be like:
  1. Pagination Manager (Singleton, managed either by plain Singleton pattern or by Spring). This will be the main component in whole design and will provide methods like
    1. register pagination user, with parameters like data provider name, search and sort criteria. 
    2. update pagination user data - to update the data retrieval attributes specified at the time of registration
    3. un-register pagination user, to remove the pagination user data from Pagination Manager cache
    4. get next page
    5. get previous page
    6. get first page
    7. get last page
    8. get page, with page number as parameter
  2. Pagination User
    1. It will represent the identity of a particular client and will contain various client specific attributes like data retrieval, search, and sort criteria.
    2. It will be created by Pagination Manager, whenever any client will register itself with the Pagination Manager for its services.  Pagination Manager will store it in cache to track the state and client specific attributes.
  3. Pagination Data Provider - This component will own the responsibility to retrieve data from repository. It should be an interface, whose implementation will be provided by client (or a generic implementation provided by application framework).
  4. Data Page - A standard data structure (a DTO) to return the pagination data page and some other related information to client from Pagination Manager
Pagination Manager component can be a server side component, which can be exposed to client by application specific remote service technology, like as web service or EJB etc. If required, a Pagination Manager's client delegate utility class can be made to hide the complexity for client to access the server component. 

Now, I suggest to read the tentative flow above again. You will understand more fine points now.

Special Considerations:

- It might be possible that client gets discarded before un-registering itself from Pagination Manager. In that case, associated Pagination User object will never be cleaned from Pagination Manager cache. 
Solution: 
  1. Pagination Manager needs to keep track of inactive client. A timeout property can be used, and it can be made configurable by using property file, or application specific configuration framework. Pagination Manager can run a demon thread to keep checking the inactive client beyond this timeout limit and can clean it. However, in this case, client either needs to keep pinging the Pagination Manager by using some keep alive protocol or need to manage a scenario where Pagination Manager is throwing exception stating that I don't know any client with specified client id. 
  2. Other solution could be, we may also explore the possibility to keep this Pagination Manager component on client side as one instance for one client. Then client can decide when to discard the Pagination Manager.
This design will use some design patterns like, Singleton, Value List Handler, DTO, Iterator etc. Class level design can certainly be different for each implementation, that is low level detail. 

Hope above design will help you to create or understand Pagination Component Design. There can be many more opportunity to improve this design. It would be nice to have any inputs for that. 

If you like the article, you may contribute by:
  • Posting your comments which will add value to the article contents
  • Posting the article link on Social Media using the Social Media Bookmark bar
  • Consider joining us at 'Java Technology Enthusiasts' linkedin group to participate in discussions
  • Connecting with 'VedantaTree' on Facebook (https://www.facebook.com/VedantaTree)

People who read this post also read :



2 comments:

Ploot said...

I always believe more code you write more bugs you expect and hence waste time in development, testing etc. So why dont you look into Spring DATA, rather than re-inventing it from scratch. Your effort and details appreciated though.

Mohit Gupta said...

Using a popular framework is always recommended, if it can meet the requirements. Reusing the knowledge is a way to devise more knowledge. I agree with this.

This discussion may help to understand the concept how Pagination works under the hood and may further contribute to customize the implementations if required.

Post a Comment