Inspired by Sinatra, Geryon is a library that runs on top of Netty 4, helping you build reactive HTTP services in the JVM.
repositories {
maven {
url "https://dl.bintray.com/geryon/releases"
}
}
dependencies {
compile "org.geryon:geryon:0.0.4"
}
libraryDependencies +=
"org.geryon" %% "geryon-scala" % "0.0.4"
For now on, every single available feature of Geryon will be showed over here. Since Geryon was developed just to be an HTTP layer for your application, not a fullstack framework, there's not much for you to learn.
//this import does all the trick
import static org.geryon.Http.*;
public class Sample {
public static void main(String[] args) {
get("/hello", request -> supply(() -> "Hello, " + request.queryParameters().get("name")));
}
}
//this import does all the trick
import org.geryon.Http.*
fun main(args: Array<String>) {
get("/hello") { supply { "hello, ${it.queryParameters()["name"]}" } }
}
//this import does all the trick
import org.geryon.scaladsl._
object Sample extends App {
get("/hello") { implicit request => supply { s"hello, ${param("name")}}" } }
}
Your app will be running at 8080.
Simple Server in Java ~ Simple Server in Kotlin ~ Simple Server in Scala
For now, these are all the http methods available:
get
post
put
delete
patch
options
head
trace
connect
get("/path", request -> futureResponse)
get("/path") { request -> futureResponse }
get("/path") { implicit request => futureResponse }
Geryon offers a simple matcher for you implement your own validation, thus you can validate, based on the request, if the handler is the right one.
get("/path", request -> boolean, request -> futureResponse)
get("/path", request -> boolean) { request -> futureResponse }
get("/path", request => boolean) { request => futureResponse }
get("/path/:myParameter", request -> {
final String myParameter = request.pathParameters().get("myParameter");
//do whatever you want to do over here
return futureResponse;
})
get("/path/:myParameter") { //in Kotlin, you can also omit the parameter if a function has only one parameter
//you can use the parameter using the keyword "it"
val myParameter = it.pathParameters()["myParameter"]
//do whatever you want to do over here
futureResponse
}
get("/path/:myParameter") { implicit request =>
val myParameter = pathParameter("myParameter") //or just param("myParameter")
//do whatever you want to do over here
futureResponse
}
get("/path", request -> {
final String myParameter = request.queryParameters().get("myParameter");
//do whatever you want to do over here
return futureResponse;
})
get("/path") { //in Kotlin, you can also omit the parameter if a function has only one parameter
//you can use the parameter using the keyword "it"
val myParameter = it.queryParameters()["myParameter"]
//do whatever you want to do over here
futureResponse
}
get("/path") { implicit request =>
val myParameter = queryParameter("myParameter") //or just param("myParameter")
//do whatever you want to do over here
futureResponse
}
get("/path", request -> {
final String myParameter = request.matrixParameters().get("path").get("myParameter");
//do whatever you want to do over here
return futureResponse;
})
get("/path") { //in Kotlin, you can also omit the parameter if a function has only one parameter
//you can use the parameter using the keyword "it"
val myParameter = it.matrixParameters()["path"]!!["myParameter"]
//do whatever you want to do over here
futureResponse
}
get("/path") { implicit request =>
val myParameter = matrixParameter("path" -> "matrixParameter")
//if you have more than one matrix parameter per path, you can do this:
//val (myParam1, myParam2) = matrixParameter("path" -> ("myParam1", "myParam2"))
//do whatever you want to do over here
futureResponse
}
get("/path", request -> {
final String myParameter = request.headers().get("myParameter");
//do whatever you want to do over here
return futureResponse;
})
get("/path") { //in Kotlin, you can also omit the parameter if a function has only one parameter
//you can use the parameter using the keyword "it"
val myParameter = it.headers()["myParameter"]
//do whatever you want to do over here
futureResponse
}
get("/path") { implicit request =>
val myParameter = header("myParameter")
//do whatever you want to do over here
futureResponse
}
post("/path", request -> {
final String body = request.body();
//do whatever you want to do over here
return futureResponse;
})
post("/path") { //in Kotlin, you can also omit the parameter if a function has only one parameter
//you can use the parameter using the keyword "it"
val body = it.body()
//do whatever you want to do over here
futureResponse
}
post("/path") { implicit request =>
val requestBody = body
//do whatever you want to do over here
futureResponse
}
Basically, a Request contains the following fields:
url: String
rawPath: String
body: String
contentType: String
method: String
headers: Map[String, String]
queryParameters: Map[String, String]
pathParameters: Map[String, String]
matrixParameters: Map[String, Map[String, String]]
In Scala, you can use a series of methods which takes an implicit request to avoid boilerplate code:
val pathParam = pathParam("pathParam")
val queryParam = queryParam("queryParam")
val pathOrQueryParam = param("param") //this method tries to get the path parameter with the informed key, if there is none, tries to get a query parameter
val header = header("header")
val (matrixParam1, matrixParam2) = matrixParameter("path" -> ("matrixParam1", "matrixParam2"))
val requestBody = body
val requestUrl = url
val requestContentType = contentType
body: String
httpStatus: Int
headers: Map[String, String]
contentType: String
You always create a response using a response builder. In Java, Kotlin or Scala, there's already a method called "response", which is a response builder that helps you build your response
response()
.body("this is the response body")
.httpStatus(201)
.header("headerName", "headerValue")
.header("headerName2", "headerValue2")
.contentType("text/plain")
.build();
response
.body("this is the response body")
.httpStatus(201)
.header("headerName" -> "headerValue")
.header("headerName2" -> "headerValue2")
.contentType("text/plain")
.build()
There are a bunch of predefined responses already created to help you return your response in a very easy way:
ok();
ok("response body");
created("https://location");
created("https://location", "response body");
noContent();
accepted();
accepted("response body");
notFound();
notFound("response body");
conflict();
conflict("response body");
unauthorized();
unauthorized("response body");
internalServerError();
internalServerError("response body");
ok
ok("response body")
created("https://location")
created("https://location", "response body")
noContent
accepted
accepted("response body")
notFound
notFound("response body")
conflict
conflict("response body")
unauthorized
unauthorized("response body")
internalServerError
internalServerError("response body")
Of course, if you feel like we could add other predefined response, feel free to ask or to pull request. ;)
port(9090);
defaultContentType("application/json");
eventLoopThreadNumber(2);
defaultHeader("X-Powered-By", "geryon");
defaultHeader("X-Powered-By" -> "geryon")
handlerFor(Exception.class, (e, r) -> internalServerError(String.format("ups, you called %s and it seems that an exception occurred: %s", r.url(), e.getMessage())));
handlerFor(Exception::class.java) { exception, request ->
internalServerError("ups, you called ${request.url()} and it seems that an exception occurred: ${exception.message}")
}
handlerFor[RuntimeException] { implicit request => exception =>
internalServerError(s"ups, you called $url and it seems that an exception occurred: ${exception.getMessage}")
}
//TODO