Sinatra inspired library for building REST microservices in Java 8
Switch branches/tags
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
core
example
.gitignore
.travis.yml
LICENSE
README.md
pom.xml

README.md

Spur Framework

Maven Central Build Status

A Sinatra inspired library for building REST microservices in Java 8. Spur for the cowboy in us!

Lightweight, at 4.6MB in size.

Simple

package com.example;
import com.clianz.spur.SpurServer;

public class BasicExample {
    public static void main(final String[] args) {
        new SpurServer()
            .get("/", (req, res) -> res.send("Hello World"))
            .start();
   }
}

Non-Blocking by Default

The server is build around single-threaded event loop by default (reactive pattern).

IMPORTANT: Do not block the thread!

  • JDBC queries are blocking by default, look into NoSQL with an async clients instead.
  • Watchout for synchronous HTTP client, pick an async one instead.

If blocking code is necessary, it can still be enabled through options.

server.start(new SpurOptions().enableBlockableHandlers(false)

Request Validator Built-in

Declare the model with Bean Validator 1.1 tags.

public class Car {
    @Min(1)
    private int doors;
    private String name;
    ...
}

Any HTTP request body of this type will trigger the validation automatically.

Request/Response JSON Marshaling/Unmarshaling

Server will automatically parse to/from JSON:

new SpurServer()
        .post("/test-drive", Car.class, (req, res) -> {
            Car car = req.body();
            log.info("Validated with Bean Validator 1.1: " + car.getName());
            log.info("Sending request body back as response.");
            res.send(car);
        })
        .start();

Simple Scheduler

server.schedule(60, () -> LOGGER.info("This is a runnable task that triggers every 60 seconds"));

Server Side Event (SSE) Support

server.sse("/sse");
server.broadcastSse("/sse", "A Server-Sent-Event (SSE) to everyone listening for events on the endpoint.");

server.schedule(5,
        () -> server.broadcastSse("/sse", sseConn -> sseConn.send("Constant spam, by SSE")));

Web-Socket Support

server.websocket("/myapp", res -> {
    LOGGER.info("[OnConnectEvent] A user has connected");
    res.send("Welcome!");
}, (msg, res) -> {
    LOGGER.info("[OnMessageEvent] User message received: " + msg);
    res.send("I heard you say: " + msg);
});
server.broadcastWebsockets("/myapp", "Everyone connected to the websocket path /myapp will see this");

server.broadcastWebsockets("/myapp",
        "This message will broadcast to websocket users on the path /myapp only if the predicate operator on the key's value is true",
        "attrKey", attrVal -> attrVal != null);

HTTP Request Filter/Validator

Since this library does not support sessions by design, JWT should be used for auth.

Filter/pre-request validator may be used for this:

server.preFilterRequests(req -> !req.header("deny")
        .isPresent(), res -> res.status(StatusCodes.FORBIDDEN)
        .send());

Note: This is not applicable web-sockets or SSE.

Other Server Options

Some other options that can be configured via server.start(new SpurOptions()...)

  • forceHttps
  • enableCorsHeaders
  • enableBlockableHandlers
  • enableGzip
  • gzipMaxSize
  • enableBasicAuth
  • host
  • port
  • enableHttps
  • sslContext (required when using https)
  • httpsPort
  • enableHttp2 (only with https)
  • requestParseTimeOut
  • maxEntitySize

Examples

See: Examples code

Complete sample project: https://github.com/icha024/spur-example