spray-extensions its a simple library with useful tools for develop web apps with Spray.
Stable OSS Sonatype
"com.github.jarlakxen" %% "spray-extensions" % "1.0"
1.0
- Add scalate support.
- Add json filtering.
- Add pagination support.
The trait PaginationDirectives offers some helpers for handling pagination:
path("filter-test") {
pagination { page =>
complete {
page match {
case Some(page) => ... // A page was requested
case None => ... // No page was requested
}
}
}
}
The page object has this format
sealed trait Order
object Order {
case object Asc extends Order
case object Desc extends Order
}
case class PageRequest(index: Int, size: Int, sort: Map[String, Order])
This is an example of url: /filter-test?page=1&size=10
or /filter-test?page=1&size=10&sort=name,asc;age,desc
The name of the parameters can be configured through Typesafe Config:
spray {
extensions {
rest{
pagination{
index-param-name = "page"
size-param-name = "size"
sort-param-name = "sort"
asc-param-name = "asc"
desc-param-name = "desc"
sorting-separator = ";"
order-separator = ","
totalelements-header-name = "total_elements"
}
}
}
}
When you replay a page, you sometime needs to send te total number of elements. This is usefull for the client for knowing how many pages they are. For this scenario there is:
path("filter-test") {
pagination { page =>
complete {
page match {
case Some(page) => {
val response = PageResponse(List("test"), 10)
completePage(response)
}
case None => ... // No page was requested
}
}
}
}
The total number of elements is sended in the header total_elements
The trait FiltersDirectives offers some helpers for filtering the json response:
val JsonArrayFull = """[
{
"name":"user1",
"password":"1234",
"meta":{"email":"user1@email.com", "age": 12}
},
{
"name":"user2",
"password":"0000",
"meta":{"email":"user2@email.com", "age": 20}
}
]"""
path("filter-test") {
pagination { page =>
filterResponse(resolver.json4s) {
complete { HttpEntity(ContentTypes.`application/json`, JsonArrayFull) }
}
}
}
The filterResponse directive required a resolver, depending of the json parser:
- resolver.json4s
- resolver.'spray-json'
You need to add the dependency to the json parser in you build.sbt ( "spray-json" or "json4s-jackson")
Using this url: /filter-test?filter=name
. The result is: [{"name":"user1"},{"name":"user2"}]
Using this url: /filter-test?filter=name;meta;!meta.email
. The result is: [{"name":"user1","meta":{"age":12}},{"name":"user2","meta":{"age":20}}]
In the last example the operator !
is used to exclude fields.
You can customize the filter separator, changing the property spray.extensions.rest.filter.separator
.
The trait ScalateSupport offers some helpers for using the scalate template engine. This is usefull if you, for example, want to use mustache.
path("filter-test") {
pagination { page =>
mustache("index", Map("USER_NAME" -> "Test"))
}
}
In this example the file /templates/index.mustache is loaded by scalate. The base path can be changed, by the property spray.extensions.view.templates-path
.