• 13
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

name Punditsdkoslkdosdkoskdo

How to keep paginated data on sync with the backend?

I'm building an Android App and I've been struggling to figure out the best way to keep paginated data on sync with the backend.

For example, let’s say that we have a GET /building?&status=free&page=1&size=5 endpoint. That fetches an array of “building” JSON objects available to rent.

The response being something like this:

{
    "data": [
        {
            "id": 1,
            "street": "Some street name 1",
            "status": "free",
        },
        {
            "id": 2,
            "street": "Some street name 2",
            "status": "free",
        },
        {
            "id": 3,
            "street": "Some street name 3",
            "status": "free",
        },
        {
            "id": 4,
            "street": "Some street name 4",
            "status": "free",
        },
        {
            "id": 5,
            "street": "Some street name 5",
            "status": "free",
        }
    ],
    "metadata": {
        "total_pages": 4,
        "page_size": 5,
        "current_page": 1
    }
}

Let’s say that on the backend you have up to 20 buildings available to rent. You just fetched the first page.

You mark the fourth and fifth building as “rented” so they’re no longer available. Let’s image that you do it through some UI button and send a PUT request to update the status of each. Something like PUT /building/4?status="rented" and PUT /building/5?status="rented"

The records on the backend would change to this state:

1|First Building |Some street|Free
2|Second Building|Some street|Free
3|Third Building |Some street|Free
4|Forth Building |Some street|Rented
5|Fifth Building |Some street|Rented

Now on the backend, if we query the available buildings we have something like:

1|First Building  |Some street|Free
2|Second Building |Some street|Free
3|Third Building  |Some street|Free
6|Sixth Building  |Some street|Free
7|Seventh Building|Some street|Free

Now if we trigger the same request, but for the second page, something like GET /building?&status=free&page=2&size=5 we are going to get something like:

{
    "data": [
        {
            "id": 8,
            "street": "Some street name 8",
            "status": "free",
        },
        {
            "id": 9,
            "street": "Some street name 9",
            "status": "free",
        },
        {
            "id": 10,
            "street": "Some street name 10",
            "status": "free",
        },
        {
            "id": 11,
            "street": "Some street name 11",
            "status": "free",
        },
        {
            "id": 12,
            "street": "Some street name 12",
            "status": "free",
        }
    ],
    "metadata": {
        "total_pages": 4,
        "page_size": 5,
        "current_page": 2
    }
}

Hence missing the 6th and 7th building that are now on the first page.

Anyone knows any way to handle this properly? Some solutions that I’ve used implied using socket messages to refresh these changes on the client-side. But still, not the fanciest solution out there.

I hope that I made myself clear, feel free to ask me for feedback if I missed anything.

Thanks

It might simplify your life to change the semantics of your resources.

GET /building?&status=free&from=1&to=5

That's a single resource that describes a fixed set of items, which may or may not be present depending on whether or not they satisfy the filter. The next page is

GET /building?&status=free&from=6&to=10

And so on.

Working with timelines describes a similar idea, using an id and a count

GET /building?&status=free&max_id=5&count=5
GET /building?&status=free&max_id=10&count=5
  • 1
Reply Report
    • Hey this is actually a great solution, and having a well-known platform like Twitter implement it is a sign that is a reliable solution. I'm just going to keep this post open a while, in case that someone posts something useful. But so far I think, this is the way to go. Thanks!
    • Accepted answer, I think that we're going to go this way plus using websockets to keep on sync with any change from the backend. Usually I've seen that the way to go is using Firebase to keep all your clients (mobile, web platform, etc) on sync, but that would require a major refactor right now. Thanks for the info.