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> 
 JarCasting
 JarCasting