Some content

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).

LET'S GET STARTED

For REST API: @Web[REST]

@WebGet, @WebPost, @WebPut, @WebDelete

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: @WebModelHandler, Freemarker

Cascading @WebModelHandler(s), Freemarker templating, cascading _frame.ftl

@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>
Snow Overview