Last active
June 11, 2018 15:58
-
-
Save juancho088/0478914ee4ae425cb4d0ac41fa7b9c90 to your computer and use it in GitHub Desktop.
Include new models for HAL
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
// You can use the same models.kt class | |
// ------------------------------------------------------ | |
// HTTP and W3C compliant models for HATEOAS/HAL | |
// ------------------------------------------------------ | |
/** | |
* A link relation indicating what is the first, last, previous and next resource | |
* This is a good practice for self discovery using HAL http://stateless.co/hal_specification.html | |
* @property value Enum value | |
*/ | |
enum class LinkRel(val value: String) { | |
NEXT("next"), | |
FIRST("first"), | |
LAST("last"), | |
SELF("self") | |
} | |
/** | |
* Resource link | |
* @property rel Type of link | |
* @property url URL String | |
*/ | |
data class Link(var rel: LinkRel, var url: URL) | |
/** | |
* Metadata of a specific page, in case of HAL it's always good practice to return context data | |
* @param limit Max amount of objects to show per page (like SQL LIMIT) | |
* @param offset From which element we start to count | |
* @param count Total elements | |
* @property totalPages Total pages that it's basically the ceil(COUNT/LIMIT) | |
* @property pageNumber Current page that it's basically the ceil(OFFSET+1/LIMIT) | |
* @property totalElements It's equals to COUNT | |
*/ | |
class PageMetadata(limit: Int, offset: Int, count: Int) { | |
val totalPages: Int = ceil(count.toDouble() / limit.toDouble()).toInt() | |
val pageNumber: Int = ceil((offset.toDouble() + 1) / limit.toDouble()).toInt() | |
val totalElements: Int = count | |
val first: Boolean | |
get() = pageNumber == 1 | |
val last: Boolean | |
get() = pageNumber == totalPages | |
override fun toString(): String { | |
return "PageMetadata(totalPages=$totalPages, pageNumber=$pageNumber, " + | |
"totalElements=$totalElements, first=$first, last=$last)" | |
} | |
} | |
/** | |
* In case of multiple elements we reply with a page, that includes the data and metadata of a set of objects | |
* @param sort Map of values to sort (based on the URL params, that means that we don't include ?page & ?size) | |
* @param limit Max amount of objects to show per page (like SQL LIMIT) | |
* @param offset From which element we start to count | |
* @property content List of objects | |
* @property links HAL links | |
* @property sort Way to sort our results based on URL params | |
* @property metadata HAL metadata | |
*/ | |
class Page<T>(sort: Map<String, Any>, limit: Int, offset: Int, count: Int, | |
var content: List<T>, var links: List<Link> = emptyList()): Model { | |
override var id: Int? | |
get() = null | |
set(value) {} | |
var sort: Map<String, Any> = sort | |
get() = field.minus(arrayOf("page", "size")) | |
val metadata: PageMetadata = PageMetadata(limit, offset, count) | |
override fun toString(): String { | |
return "Page(content=$content, sort=$sort, links=$links, metadata=$metadata)" | |
} | |
} | |
/** | |
* Desired pagination | |
* @property page Page Number to present | |
* @property size Size of the pages | |
*/ | |
data class Pagination(var page: Int, var size: Int) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment