gyokuro

A tiny framework for creating web apps in Ceylon


shared void run() {
    get("/hello", (req, resp) => "Hello, World!");
    get("/users/:username", `showUser`);

    Application().run();
}

Template showUser(String username)
    => render("templates/user", map {"user" -> username});

Introducing gyokuro

gyokuro is a framework written in Ceylon, similar to Sinatra and Spark for creating web applications with very little boilerplate. It is based on the Ceylon SDK and uses ceylon.http.server.

Current version: 0.3.1 (Sept. 24, 2017)


Easy and type-safe bindings

Routes can be declared to bind paths to simple (Request, Response) function handlers. You can also use references to functions with more complex signatures, and gyokuro will automatically bind GET/POST/path parameters by name.

get("/hello", (req, resp) => "Hello, World!");
post("/user/edit/:id", `editUser`);

void editUser(Integer id, String name, String password) {}
route("user")
shared controller class UserController() {
    route("edit")
    shared void edit(Integer userId, String username) {}

    route("list")
    shared User[] listUsers() => ...
}

Annotated controllers

In addition to the get() and post() functions, you can annotate classes or objects with controller, allowing you to group multiple routes in the same declaration.

Templating

gyokuro does not ship with any particular templating engine, but it’s very easy to plug any existing engine via the View API. Handlers don’t need to be aware of which templating engine is used, they simply call the render function with a template name and a context map.

Template greet(String who) 
        => render("greetingTpl", map {"name" -> who});

// Sample template renderer
object helloRenderer satisfies TemplateRenderer {
    render(Template template, Map<String,Anything> context, 
            Request req, Response resp)
            => resp.write("Hello, ``context.get("name") else "world"``!");
}

Wait, there’s more!

For a complete description of gyokuro’s features, head off to the docs, or keep reading to get you started on a new project!


Getting started

  • if you haven’t already done so, grab a copy of the current Ceylon distribution or a plugin for your favorite IDE
  • create a new Ceylon project and import gyokuro:
module com.example.mymodule "1.0.0" {
    import net.gyokuro.core "0.3.1";
}
  • write your first application:
shared void run() {
    get("/hello", (req, resp) => "Hello, world!");

    Application().run();
}

The above example will bootstrap a web server that runs by default on 0.0.0.0:8080. The path /hello will be bound to a handler that takes two parameters, a Request and a Response, and returns a String containing "Hello world". This string will be the response body.

Running examples

The GitHub repository contains a few examples that show how to use gyokuro. You can run them very easily with the following commands:

  • git clone https://github.com/bjansen/gyokuro.git
  • cd gyokuro
  • ./ceylonb
  • ./ceylonb compile
  • ./ceylonb run gyokuro.demo.rest

Livin’ on the edge

gyokuro is still in development, so if you want to test the very latest bleeding edge version, you can build it from sources:

  • clone the project: git clone https://github.com/bjansen/gyokuro.git
  • go to the cloned project: cd gyokuro
  • build the project: ceylon compile
  • copy the generated module to your local Ceylon repository to use it in other projects: ceylon copy -o ~/.ceylon/repo net.gyokuro.core
  • enjoy

Documentation

The full documentation for the latest version (0.3.1) is available here:

The full documentation for the development version (0.4-SNAPSHOT) is also available.

Performance

See the performance tests page.