Last active
September 6, 2017 15:43
-
-
Save ksmandersen/46c7b89ff106eefced6750933b566b37 to your computer and use it in GitHub Desktop.
Paginate requests based on Fluent model queries in Vapor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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