A Google Guice based Micro Web Framework to build
scalable Java Web Application and Web Services

Optimized for creating REST API & SEO optimized pages; Lightweight (300KB); ZERO-XML configuration; Productivity of Ruby/PHP/Node.js but in modern Java; .js/.css WebBundle support (concatination and caching); .less builtin server side compilation/caching support (i.e. mylessfile.less.css); Based on Google Guice for DI and AOP; Fully Open Source (Apache V2 License).

For REST API: @Web[REST]

ANY Java methods annotated with @Web*** will get auto-dicovered and http-bound by Snow, and the Class will be managed by Guice. So, doing this:

@WebGet("/api/item")
public Item getItem(@WebParam("id") Long itemId /*,...dynamic parameter binding...*/){
  Item item = itemDao.getItem(itemId);
  return item;
}

Will expose a REST API for GET "http://localhost:8080/myapp/api/item?item=123" with a JSON result like:

{"id": 123,
  "title": "First item title",
  "description": "A not very creative description."}

Any @Web*** annotated method can have a dynamic list of parameters that will get bound with HTTP request data values or even Google Guice managed bindings. For example, a @WebDelete REST API could be written like

@WebDelete("/api/item-{id}")
public Item getItem(@PathVar("id") Long itemId, ItemDao itemDao /*Inject from Guice*/){
  boolean success = itemDao.delete(itemId);
  return "{'success':" + success + "}";
}    

In the example above, the itemId method parameter is acquired from the path with @PathVar annotation, and the ItemDao is acquired via Google Guice, since there is no default or application @WebParamResolver for it.

For Page Rendering: @WebModelHanler

@WebModelHandler(s) get invoked up to the path to build a @WebModel Map

@WebModelHandler(startsWith="/")
public Item getItem(@WebModel Map m /*,...*/){
  m.put("appVersion","1.3.1");
}

@WebModelHandler(startsWith="/item/info")
public Item getItem(@WebModel Map m, @WebParam("itemId") Long itemId /*,...*/){
  Item item = itemDao.getItem(itemId);
  m.put("item",item);
}    

Would match to a /webapp/item/info.ftl file like:

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <p>Item id: ${item.id}</p>
    <p>Item title: ${item.title}</p>
    <p>Item description: ${item.description}</p>
    <footer>(app version ${appVersion}</footer>
  </body>
</html>  

With a result for http://localhost:8080/webappname/item/info?itemId=123 as:

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <p>Item id: 123</p>
    <p>Item title: First item title</p>
    <p>Item description: A not very creative description.</p>  
    <footer>(app version 1.3.1)</footer>
  </body>
</html>  

Snow also provides a simple customizable way to cascade template to ease the creation of muli-pages applications. The result above, should be created as:

A /webapp/_frame.ftl which will be included for all pages below the "webapp/" folder.

<!DOCTYPE html>
<html>
  <head>...</head>
  <body>
    [@includeFrameContent /]
    <footer>(app version ${appVersion})</footer>
  </body>
</html>

The [@includeFrameContent /] will include either the target page or another sub-folder "_frame.ftl" if present.

So, now, we can just have the item/info template page at /webapp/item/info.ftl as:

<p>Item id: ${item.id}</p>
<p>Item title: ${item.title}</p>
<p>Item description: ${item.description})</p>