Skip to content

Instantly share code, notes, and snippets.

@ariesmcrae
Last active June 3, 2017 05:03
Show Gist options
  • Save ariesmcrae/6cd9b1c76d6ed440d9ae53e063b654ef to your computer and use it in GitHub Desktop.
Save ariesmcrae/6cd9b1c76d6ed440d9ae53e063b654ef to your computer and use it in GitHub Desktop.
Pagination through REST API requests

Pagination through REST API requests

It emulates the behavior of Spring Data REST JPA

Imagine you have this table in your database

email
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]

Imagine also that the requesting webapp client wants to receive only 2 rows at a time.

Client SQL (MySQL) Result
/v1/email?page=0&size=2 select * from email LIMIT 0, 2 [email protected] [email protected]
/v1/email?page=1&size=2 select * from email LIMIT 2, 2 [email protected] [email protected]
/v1/email?page=2&size=2 select * from email LIMIT 4, 2 [email protected] [email protected]
/v1/email?page=3&size=2 select * from email LIMIT 6, 2 [email protected] [email protected]

Formula

LIMIT [page x size], [size]

totalPages = (totalElements = size -1) / size

    where:
        totalPages = the total number of pages for the client query.
        totalElements = total number of rows for the client query.
        size = aka page size. The number rows to return per client request.

Request / Response example 1

GET /v1/emails?page=0&size=2
 
{
  _embedded: {
    emails: [
      {
        email: "[email protected]",
        _links: {
          self: {
            href: "http://api.acme.com/v1/emails/[email protected]"
          },
          email: {
            href: "http://api.acme.com/v1/emails/[email protected]"
          }
        }
      },
      {
        email: "[email protected]",
        _links: {
          self: {
            href: "http://api.acme.com/v1/emails/[email protected]"
          },
          email: {
            href: "http://api.acme.com/v1/emails/[email protected]"
          }
        }
      }
    ]
  },
  _links: {
    first: {
      href: "http://api.acme.com/v1/emails/page=0&size=2"
    },
    self: {
      href: "http://api.acme.com/v1/emails/page=0&size=2"
    },
    next: {
      href: "http://api.acme.com/v1/emails/page=1&size=2"
    },
    last: {
      href: "http://api.acme.com/v1/emails/page=3&size=2"
    }
  },
  page: {
    size: 2,
    totalElements: 8,
    totalPages: 4,
    number: 0
  }
}

Request / Response example 2

GET /v1/emails?page=1&size=2
 
{
  _embedded: {
    emails: [
      {
        email: "[email protected]",
        token: "3333333333333333333333333",
        _links: {
          self: {
            href: "http://api.acme.com/v1/emails/[email protected]"
          },
          email: {
            href: "http://api.acme.com/v1/emails/[email protected]"
          }
        }
      },
      {
        email: "[email protected]",
        _links: {
          self: {
            href: "http://api.acme.com/v1/emails/[email protected]"
          },
          email: {
            href: "http://api.acme.com/v1/emails/[email protected]"
          }
        }
      }
    ]
  },
  _links: {
    first: {
      href: "http://api.acme.com/v1/emails?page=0&size=2"
    },
    prev: {
      href: "http://api.acme.com/v1/emails?page=0&size=2"
    },
    self: {
      href: "http://api.acme.com/v1/emails?page=1&size=2"
    },
    next: {
      href: "http://api.acme.com/v1/emails?page=2&size=2"
    },
    last: {
      href: "http://api.acme.com/v1/emails?page=3&size=2"
    }
  },
  page: {
    size: 2,
    totalElements: 8,
    totalPages: 4,
    number: 1
  }
}

Note: The above response adheres to HATEOAS using HAL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment