spur-framework

Spur framework

License

License

Categories

Categories

CLI User Interface
GroupId

GroupId

com.clianz
ArtifactId

ArtifactId

spur-parent
Last Version

Last Version

0.0.3
Release Date

Release Date

Type

Type

pom
Description

Description

spur-framework
Spur framework
Project URL

Project URL

http://github.com/icha024/spur
Source Code Management

Source Code Management

http://github.com/icha024/spur

Download spur-parent

Filename Size
spur-parent-0.0.3.pom 3 KB
Browse

How to add to project

<!-- https://jarcasting.com/artifacts/com.clianz/spur-parent/ -->
<dependency>
    <groupId>com.clianz</groupId>
    <artifactId>spur-parent</artifactId>
    <version>0.0.3</version>
    <type>pom</type>
</dependency>
// https://jarcasting.com/artifacts/com.clianz/spur-parent/
implementation 'com.clianz:spur-parent:0.0.3'
// https://jarcasting.com/artifacts/com.clianz/spur-parent/
implementation ("com.clianz:spur-parent:0.0.3")
'com.clianz:spur-parent:pom:0.0.3'
<dependency org="com.clianz" name="spur-parent" rev="0.0.3">
  <artifact name="spur-parent" type="pom" />
</dependency>
@Grapes(
@Grab(group='com.clianz', module='spur-parent', version='0.0.3')
)
libraryDependencies += "com.clianz" % "spur-parent" % "0.0.3"
[com.clianz/spur-parent "0.0.3"]

Dependencies

There are no dependencies for this project. It is a standalone project that does not depend on any other jars.

Project Modules

  • core
  • example

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

Versions

Version
0.0.3