Skip to content

Instantly share code, notes, and snippets.

@ksmandersen
Last active September 6, 2017 15:43
Show Gist options
  • Save ksmandersen/46c7b89ff106eefced6750933b566b37 to your computer and use it in GitHub Desktop.
Save ksmandersen/46c7b89ff106eefced6750933b566b37 to your computer and use it in GitHub Desktop.
Paginate requests based on Fluent model queries in Vapor
import Foundation
import Vapor
import FluentProvider
struct Paginator<T: Model> where T: JSONRepresentable {
let query: Query<T>
let request: Request
let perPage: Int
init(query: Query<T>, request: Request, perPage: Int = 25) {
self.query = query
self.request = request
self.perPage = perPage
}
}
extension Paginator: JSONRepresentable {
func makeJSON() throws -> JSON {
let requestedPage = request.query?["page"]?.int ?? 0
let requestedOffset = perPage * requestedPage
let totalCount = try query.count()
let page = requestedOffset <= totalCount ? requestedPage : 0
let offset = perPage * page
var nextPage: String? = nil
var previousPage: String? = nil
if offset + perPage <= totalCount {
nextPage = "\(request.uri.path)?page=\(page + 1)"
}
if page > 0 {
previousPage = "\(request.uri.path)?page=\(page - 1)"
}
let entities = try query.limit(perPage, offset: offset).all()
var response = Node.object([:])
var paginator = Node.object([:])
try paginator.set("total", totalCount)
try paginator.set("page", page)
try paginator.set("count", entities.count)
try paginator.set("per_page", perPage)
try paginator.set("next_page", nextPage)
try paginator.set("prev_page", previousPage)
try response.set(T.entity, try entities.makeJSON())
try response.set("paginator", paginator)
return JSON(response)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment