But it looks there is a race condition due to the design of the pagination mechanism, with the page field:
Actually what you are describing is expected behavior. The API calls are independent of each other and when you perform a paged API call you are asking for a paged view of the current DB content and it is not depended on previous API call.
List of devices becomes 1, 2, 3, 4, 6, 7, 8, 9, 10, means
GET /devices?page=1&per_page=5 = 1,2,3,4,6
GET /devices?page=2&per_page=5 = 7,8,9,10
per_page works as a limit., that is a maximum number of results per page. This could be clarified in the API docs.
Yes, I understand this is the expected behavior with the current API. But it makes impossible to synchronize the list of devices with another external system.
Could we have a paging mechanism similar to what DynamoDB does for example (returning a LastEvaluatedKey which can be used to filter the next request by fetching only the items after LastEvaluatedKey)?
What you are asking for is not currently available in the device inventory APIs. It is a valuable feature, though, especially in data-sync scenarios. We recorded it in our backlog, and the product owner will prioritize it.
Please be aware that Mender 2.4, which we’ll release early June, implements new APIs for dynamic filtering, using operators (e.g., greater than) tied together with custom sorting and pagination. I believe these new API end-points are going to cover your use-case and allow a loop which emulates stateful pagination.