A Sinatra inspired library for building REST microservices in Java 8. Spur for the cowboy in us!
Lightweight, at 4.6MB in size.
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();
}
}
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)
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.
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();
server.schedule(60, () -> LOGGER.info("This is a runnable task that triggers every 60 seconds"));
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")));
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);
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.
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
See: Examples code
Complete sample project: https://github.com/icha024/spur-example