modernistik / parse-stack

Parse Server Ruby Client SDK
https://www.modernistik.com/gems/parse-stack/
MIT License
60 stars 20 forks source link

Returning result with pagination #43

Closed adsherpa closed 6 years ago

adsherpa commented 6 years ago

Is there api call already existing or extension to expand result in pagination so that can be used by client consuming parse-stack either in Ruby on Rails or react client. I am using rails 5.2 for api that interacts with parse-stack. Looking to implement paginated api response. Any help or direction would be appreciated. I am looking for something similar to the following "total_count" => 75, "links": { "self": "http://localhost:3000/posts?page_number=2&page_size=15&per_page=15", "first": "http://localhost:3000/posts?page_number=1&page_size15&per_page=15", "prev": "http://localhost:3000/posts?page_number=1&page_size=15&per_page=15", "next": "http://localhost:3000/posts?page_number=3&page_size=15&per_page=15", "last": "http://localhost:3000/posts?page_number=4&page_size=15&per_page=15" } The reason I am checking on this is to see if there was already work done in parse-stack. Thank you for your consideration. Looking forward to check your response.

apersaud commented 6 years ago

Yes, this feature is already available on Parse-Server and in Parse-Stack. You can use a combination of the count API and the :skip and :limit expressions to achieve the desired results. Creating pagination is about fetching a set of fixed number records from an offset. When doing this, I usually recommend keeping the skip and limit amounts equal to make the "math" simpler through iterations of making the links.

Assuming you have a collection of Notes.

class Note < Parse::Object
  property :author
end

Assuming you want a page_size of 100 records. Then you can set the skip and limit to this value, and manage it with the current page number.

  page_size = 100

  # get total records where author is "mk"
  total_count = Note.count(author: "mk")
  # get number of pages required
  number_of_pages = ( total_count / page_size.to_f ).ceil

With this, you can now fetch any page you want, with the simple equation (assuming page numbers start at 1):

  # calculate skip count based on current page number
  skip_count = (page_number - 1) * page_size

And do the query:

  # fetch 100 results where author is "mk" ordered by created_at
  results = Note.all(author: "mk", order: :created_at, skip: skip_count, limit: 100)

  # Example:
  page_number = 4
  skip_count = (page_number - 1) * page_size # => 300

  # Skip the first 300 records and fetch the next 100
  results = Note.all(author: "mk", order: :created_at, skip: skip_count, limit: 100)

The records returned and ordered are all dependent on the rest of the query parameters you pass. To build your JSON hash, you would just iterate through all the number of pages with the page size and also pass any specific query parameters in your url.

One trick for development - to see the compiled query, use the prepared on query so you can see the calculation.

   puts Note.where(author: "mk", skip: 100, limit: 100).pretty
# {
# "limit": 100,
#  "skip": 100,
#  "where": "{\"author\":\"mk\"}"
# }

And you can now url encode the hash in the query parameter (though you should consider

Parse-Stack Documentation for skip Parse SDK Documentation for Parse Queries