Snappy
A tiny and powerful web framework for Java 8
Features:
- Based on Undertow handlers
- Rest with content negotiation (media type only)
- Server sent events
- Server sent events client
- Websockets
- Websocket client
- Built in simple service discovery
- Small. ~6mb
- No magic, plain and simple
- Small memory footprint
- Static files
- Rest client
- Multipart support
- Executors and schedulers managed by the server
- Extensible
- Maven uber jar plugin using Spring boot
Maven setup
<dependency>
<groupId>io.joshworks.snappy</groupId>
<artifactId>snappy</artifactId>
<version>0.6.0</version>
</dependency>
Import
import static io.joshworks.snappy.SnappyServer.*;
import static io.joshworks.snappy.http.Response.*;
Hello
public class App {
public static void main(final String[] args) {
get("/hello", req -> ok("Hello !", "txt")); //or text/plain
start(); //9000
}
}
Path parameter
public class App {
public static void main(final String[] args) {
get("/hello/{name}", req -> ok("Hello " + req.pathParameter("name"), "txt"));
start();
}
}
Receiving JSON
public class App {
public static void main(final String[] args) {
post("/users", req -> {
User user = req.body().asObject(User.class);
//..
return ok();
});
start();
}
}
Sending JSON
public class App {
public static void main(final String[] args) {
get("/users", req -> ok(new User("John Doe")));
start();
}
}
Filter
public class App {
public static void main(final String[] args) {
beforeAll("/users", req -> System.out.println("A"));
before("/users", req -> System.out.println("B"));
after("/users", (req, res) -> System.out.println("C"));
afterAll("/users", (req, res) -> System.out.println("D"));
get("/users", req -> {
System.out.println("Users");
return ok();
});
start();
// Prints:
//A
//B
//Users
//C
//D
}
}
Error handling
public class App {
public static void main(final String[] args) {
exception(Exception.class, (ex, req) -> Response.internalServerError(ex));
get("/users", exchange -> {
throw new RuntimeException("Some error");
});
start();
}
}
Serving static files
public class App {
public static void main(final String[] args) {
//from src/main/resources/static
//available on /pages
staticFiles("/pages");
// staticFiles("/pages", "someFolder"); // src/main/resources/someFolder
}
}
Uploading file
public class App {
public static void main(final String[] args) {
post("/fileUpload", req -> {
Path theFile = req.multiPartBody("theFile").file().path();
Files.copy(theFile, someOutputStream);
});
}
}
Broadcasting data with SSE
public class ClockServer {
public static void main(final String[] args) {
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
SseBroadcaster broadcaster = sse("/clock");
//curl http://localhost:9000/clock
onStart(() -> scheduler.scheduleAtFixedRate(() -> broadcaster.broadcast(new Date().toString()), 1, 1, TimeUnit.SECONDS));
start();
}
}
SSE groups / topics
public class App {
public static void main(final String[] args) {
SseBroadcaster broadcaster = sse("/subscribe/{group}", sse -> {
sse.joinGroup(sse.pathParameter("group"));
});
//curl http://localhost:9000/subscribe/group-a
//curl http://localhost:9000/subscribe/group-b
post("/publish/{group}", req -> {
String group = req.pathParameter("group");
String message = req.body().asString();
broadcaster.broadcast(group, message);
return ok();
});
}
}
Registering a parser
public class App {
public static void main(final String[] args) {
Parsers.register(myXmlParser);
get("/xml", req -> ok("<root></root>"), produces("xml"));
}
}
Resource group
public class App {
public static void main(String[] args) {
// /groupA/a
// /groupA/b
// /groupA/subgroup/c
group("/groupA", () -> {
get("/a", req -> {/* ... */});
put("/b", req -> {/* ... */});
group("/subgroup", () -> {
get("/c", req -> {/* ... */});
});
});
// /groupB/d
group("/groupB", () -> {
get("/d", req -> {/* ... */});
});
}
}
Uber jar
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>io.joshworks.snappy</groupId>
<artifactId>snappy-maven-plugin</artifactId>
<version>0.5.2</version>
</plugin>
</plugins>
</build>