Why I started another Singe-Page-Application Framework

Today I decided to start a new open source project providing a singe-page-application (SPA) framework. This sounds crazy, because we live in a time in which so many different spa frameworks are developed.

The reason why I am interested in singe-page-application frameworks is that I have an existing complex JEE Application build on JSF 2.0 and I am looking for a way to reduce the evolved complexity of my web front-end. I don’t think that JSF can compete with SPA in modern web applications. On the other hand I already have an existing Rest Service API in my application. So this is the reason why I stared to look around for a SPA framework that fits my needs.

Fist I took a look on AngularJS. This is the most common SPA Framwork. There is a big community around Angular, but also only one big company in the background. I found that Angular did not fit me needs in any way so I took another look on EmerJS. First I was fascinated from ember which is very professional. But after some time I was disappointed. Not because of the steep learning curve, but due to the high complexity. Remember: one of my goals was to reduce the complexity of my JSF web front-end. But it did not look to me like Angular or Ember will reduce this complexity – just moving it from one framework into another. Even if the result with both frameworks will be a more modern and smarter web client.

So with that background in mind, I started a new project providing my own Singe-Page-Application framework: Ben.JS.
Please note: Ben.JS was just stared and did not provide a production ready or comparable result!

What are the goals of this framework?

I am convinced that we today have fascinating web-technologies, which allow everyone to develop great web applications using HTML5 JavaScript and CSS3. I don’t think that everyone who decided to start developing a JavaScipt based web application needs a enterprise application framework like provided by ember or angular. Web applications should be based on a REST API encapsulating the business logic! (If this is not the case, stop a moment and start again from scratch.)

Based on this we can separate the application in the following parts:

  • A model – provided in the existing REST API
  • A view – represented and build on HTML and CSS3
  • A controller – fitting together the model with the view

To build a View with HTML I don’t need another framework. There are enough tools and concepts in the market. On the other hand, should the model be provided by your REST API. There are a lot of valuable books, tutorials and blogs explaining what a REST service should look like. To map the result of a REST Service call into a JavaScript object is not big deal. This happens if you just use an Ajax call to get your resource based on JSON. JavaScript is an ideal language to work with such objects in a common and flexible way.

So at the end the challenge is: how can I fit my model into the view? The goal of Ben.JS is exactly that! Ben.JS provides the controller in the MVC – simply that!

Now I will explain some of the core concepts of Ben.JS

1. Based on jQuery

Ben.JS is based on jQuery. jQuery is a common JavaScript library. If you now think “Oh my god! I need yet another library!” you may think about this: There is a amusing discussion that Ember has the disadvantage against Angular because of a large footprint. Using Ember you need also include jQuery – 84KB. Angular did include jQuery in a ‘light-version’ which is much smaller. In my opinion it is absolutely idiotic to discuss about more or less 100 KB footprint inside an application which is later dealing with hundreds of MB  to provide funny pictures or videos. So – working with Ben.JS forces you to also use jQuery. On the other hand you can also add any additional JavaScript library you like. For example you can combine Ben.JS together with Angular, Ember or React – there is no restriction because Ben.JS is a tiny small library. And do not worry about the footprint!

2. Controllers and Data-Binding

Data binding is a technique to establish a binding between the data reflected in the UI and the model presented by the application logic. Two way data binding means; if you change something in your model it will change the view accordingly and vice versa. If you are changing a property of your model the changed value will be reflected automatically in your UI template. Angular and Ember both provide this tight coupling of model and view. I think this is nice but absolute unnecessary. It is the standard hello-world example of these frameworks that even if you type something into a input field the value will be displayed aside in a text block which updates automatically. But why did we need this magic things?

Think about the use case of a business application:

  1. The user can see a list of datasets
  2. The user select one of these datasets
  3. The user changes the values using a input form
  4. The user submits his changes to be stored in a database

No one expects that when I type something into a input widget the data will be stored on a sever in the same time. I know this is not the goal of two-way-data binding, but what I want to point out is the following: You have to  situations where you need to synchronize the view with the model: When the user selects a dataset and when the user submits his changes. So the only thing you need is to push your model into the view and pull the data out before submitting any changes to the back-end.

For that reason Ben.JS provided exactly these two methods. Everything between is just for fun and you can do this in several ways with any framework you like.

3. Templates

A template-engine is a important part of any SPA framework. This means that you can build your view from different HTML snippets provided in separate files or folders. Loading a html snippet is no big deal, you can archive this using again the jQuery framework. Ben.JS provides a general concept to load templates in any place of your application or define specific view-templates for each controller you created with Ben.JS. When a new view-templated is loaded Ben.JS will automatically push the model into the view.

In different to other SPA frameworks templates in Ben.JS are simple html pages. You can place it anywhere and there is no special syntax necessary. Templates in Ben.JS provide data-binding and special tags like the “for-each” constructor.

4. Routing

Routing is a other central concept of SPA frameworks. The basic idea is to append the browser URL with a ‘#’ followed by a path. This allows the browsers history back navigation and the ability to bookmark such URLs. Thinking about the concepts of routing in Angualr and Ember I came to the following conclusion: A route is a specific state in a SPA. The user expect a defined view and this view need to be synchronized with the model. Looks complicating but it isn’t. At the end a route simply initializes its controllers.

In Ben.JS you can define Routes in a very simple and clear way. Ben.JS updates the URL and than initialized the registered routers. That’s all.

The Ben.JS Controller

The core of Ben.JS is its Controller concept. You don’t need to implement a controller by yourself. Concentrate on the View and the Model. The controller is provided by the Framework. To keep things simple a Controller in Ben.JS has only 4 methods:

  • push()
  • pull()
  • load()
  • init()

The push, and pull methods are used to synchronize the model. The load method is used to load View Templates. And the init method which initializes a view state. No more no less.

Keep things simple

So at the end the framework is just a small library with a concept which can be understood in some minutes. If you want to develop something special you are free to do this in the way you like. There is no corset in which you have to squeeze. There are no restrictions. You can combine it with other frameworks if you think this is useful for you. 

So, take a look at the project on GitHub  and give me your feedback if you like

Leave a Reply

Your email address will not be published. Required fields are marked *