Dec 6, 2012

Thinking about creating an new Java Web framework

Why: I love playframework v1 but not v2. However play team moves their attention away from v1.

What should be kept from v1:

  • Bytecode enhancement. This is a great stuff that enable framework and plugin developer to inject logic into Application code
  • A full stack framework. This should like Play which runs on itself instead of inside a servlet container
  • Support plugins. Though API might changed
  • Handy utility libraries for application developer, like IO, Codec, Images etc.
  • Built in simple Secure framework
  • The DB layer enable plugin different implementations, JPA, EBean, Morphia etc.
  • Built in validation
  • Easy to use asynchronous handling API, like Promise and Controller.await
  • Before, After, Final, Catch intecepters to plugin logic into request handling chain
  • Render with different template based on request.format
  • JavaExtension to template
  • And most important is Simple, Simple and Simple to application developers

What needs to be improved or changed:
  • Routing mechanism. Improve the routing performance for big routing table with more than 100 routes. This might involve code generator to generate routing source code dynamically
  • Action invocation mechanism. Reduce the use of reflection, static methods and Exception. But needs to keep the API still simple though
  • Plugin API. Support partitioned plugin API set instead of all-in-one big facade
  • Replace python stuff with pure script plus Java
  • CRUD
  • Replace default Groovy template engine with Rythm
  • Replace default JPA with Ebean ???
  • JSON support

Proposed Controller API:

public class Orders extends Controller {

  // --- Parameters used in action handling methods
  @Bind(method = Bind.ByID)
  protected Order order; // will bind to http request params with Order.findById(params.get("orderId"))
  
  @Bind(method = Bind.ById)
  protected User user;
  // -- eof Parameters
  
  // this use new return style API
  @Required("orderId")
  public Result show() {
    return new Render(order);
  }

  // this use old style API
  @Required("orderId")
  public void saveUpdate() {
    notFoundIfNull(user);
    order.save();
    render(order, user);
  }
  
  // this action method will be executed in a separate thread
  @Async
  public Result report() {
    order.save();
    List orders = ...
    return new RenderPDF(orders);
  }
  
}

Sample route file:

GET /orders/{orderId} Orders.show
POST /orders/{orderId} Orders.saveUpdate
GET /orderReport Orders.report

What do you think?