Skip to content

Instantly share code, notes, and snippets.

@juancho088
Last active June 11, 2018 15:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save juancho088/0478914ee4ae425cb4d0ac41fa7b9c90 to your computer and use it in GitHub Desktop.
Save juancho088/0478914ee4ae425cb4d0ac41fa7b9c90 to your computer and use it in GitHub Desktop.
Include new models for HAL
// 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