This article compares the ease of learning of web frameworks: Rails, Grails, Django and CodeIgniter based on the experience of learning how to use the framework and developing a toy application, MyBlog, in fixed time. More details about this test can be found here. Points of comparison will be timing, documentation, community support, steps to execute common functions, some features, lines of code and readability of solutions.
Complete source code of the implementations in each framework can be found here.
We can divide the development of the toy application into the following modules:
- User + Authentication system: A user is able to register, login, logout, etc.
- Blog: A user is able to create a blog.
- Post: A user is able to publish posts for his/her blog. These posts are listed in the front page and in each blog page.
- Comment: Users and guests can post comments.
If you would like to read a more extensive explanation, you can refer to this link.
It is important to keep in mind that this development process occurred between March and the end of July 2013, therefore notes and opinions are based on their state in those dates. The frameworks could have evolved since then.
In table 1, it is shown a comparison of developing time for each step with each framework. The same data is presented in a graph manner in figure 1. The order of columns represents the order in development. Developing with CodeIgniter required the least amount of time compared with other frameworks, 17 hours less to finish the exercise compared with Rails. Myblog application was finished with every framework in fixed time excluding Grails, which was almost finished with some errors. Developing with Django required less time than with Grails and Rails: 7 hours less.
Before comparing different steps, it will be exposed the commonalities between these frameworks.
- All of them are MVC frameworks.
- All of them have a route file to map the urls to the controller.
In the next sections, a comparison of different steps throughout development will be exposed.
Rails had an excellent documentation. It had several examples which facilitated to understand the framework, it also had a getting started guide which gave an overview of the framework and had a division between beginner and advanced topics. Furthermore, it presented the highest popularity in StackOverFlow, most questions were already asked and solved.
Grails required less than 30 hours to read documentation. Documentation was difficult to understand and there was not a general division for beginners and advanced readers. It was considered, probably a wrong consideration, that it had been read enough documentation to start implementation and it would be well understood throughout development. Therefore, Grails required more time than others in the second step, when development began, because documentation was not clear. Other sources of documentation were used to understand it and people were complaining about lacking of documentation in blogs and forums. Main problems were Shiro and Hibernate.
Django had an excellent documentation, it was easy to follow, understand and it had several examples. Most questions were solved in StackOverFlow clearly too, but it presented a bit less popularity than Rails.
CodeIgniter presented a concise and short documentation. It lacked examples but it could be completely read and understood in 23.5 hour.
In Rails, implementing the User module and authentication required the least amount of time. Probably due to the fact that it was implemented following the Ruby on Rails Tutorial. Only with this framework, an own authentication system was built. The reason was that plugins(gems in Rails vocabulary), which offered this functionality, advised to build an own authentication system if the programmer had never done that.
In Grails, implementing authentication was the most difficult task. It was not known if it should be used Shiro or Spring Security plugin. At the beginning, it was tried with Shiro, but the official documentation was complex to be understood. This was the reason why it was tried to build an own authentication system as in Rails. All over this process, some better documentation for Shiro was found and finally, Shiro authentication library was used.
Django came with a bundled authentication system which was well documented, it simply had to be understood and adapted.
CodeIgniter had a Tank Auth library which was well accepted. This library was copied into the application. The source code was easy to understand and it was modified according to requirements.
Implementing Blog, Post and Comment
The modules Blog, Post and Comment are really similar: CRUD (Create, Read, Update and Delete) operations on database tables which are related between them. Therefore, it has be chosen a small example to compare them. This example implements the following use cases and features:
- A user can create a post.
- A user can read a post, the comments associated to this post and he/she has the possibility to publish a new comment.
- The url to show a post must be friendly.
- The owner of a blog is allowed to delete comments of his/her blog.
In table 2, the steps that were followed to implement this example in each framework are shown. This allows us to compare the different methodologies used to develop with each framework. From a wide perspective, code generators were used with Rails and Grails, while class-based views were used with Django and most of the code had to be written with CodeIgniter.
Rails and Grails steps are really similar. It may be used code generators and adapt them. These generators implement the CRUD operations in a resource with basic views. You can see code generated and adapted for the post controller, the post model and the post show view in Grails and Rails. These generators can be used to agile development and make the required changes to the code.
Django offers a different approach with the class-based views, although it is possible to write similar code in Django than the one generated by Grails or Rails. It would be more time consuming than using class-based views. The Django approach requires the programmer to understand well the class-based views, their workflow and methods. This approach follows more strictly the DRY principle than Rails and Grails. In this link, views, models and a template are listed for the post module. Complete source code can be found in the source code of the full implementation. The action of creating a post is implemented by defining a class PostCreate, which is a subclass of CreateView, to create a record based on a model. The model to be used is defined and two methods are overwritten: the dispatch method and the form_valid. The first one is modified to require a user to be signed in, while the last one is modified to connect the post to a blog, afterwards it is called the super method in both cases.
CodeIgniter does not have generators neither class-based views. It requires the programmer to write most of the methods needed. It has libraries to help in the task but the active record implementation does not offer a complete set of functions to treat database records as objects. The source code for the model, controller and view is listed here. It can be seen that several methods used in the rest of the web frameworks in this comparison had to be implemented, for example: create, get_post, update, among others.
Code generated by Grails vs Rails
Rails and Grails code generated and adapted for the post controller, model and show post are listed in this link. As it can be seen, Grails did not generate a model. First, the model had to be written and afterwards the code could be generated. Code generated by Grails was larger than code generated by Rails. But Grails offered more features with the code generated: it was already prepared for internationalization and, when updating a resource, it controlled if the resource had been updated since it was retrieved. On the other hand, Rails was prepared to render JSON with the code generated. Views generated by Rails were cleaner and more concise than those generated by Grails.
Comparing general features
- Database tools: Tools for creating databases, tables, fields, get back to previous state or move forward.
- Rails had a complete functionality for managing databases. It could be created databases, tables, updated fields, among other features. Furthermore, it supported migrations: any change made to the database was stored in a file called migration which could be set up or down, to commit the changes described in the file or recover to previous state.
- In Grails, it was defined the model in a file and the database was created in HSQLDB. It is not known how difficult is to migrate from this DB to MYSQL, SQLite or others.
- Django supported creating database, although it did not have migrations. Therefore, updates in table structure had to be made with other software.
- CodeIgniter did not offer tools for creating the database.
- Active Record Implementation, searching in models and pagination: Tools for operating with records in database in an object-oriented manner. For example, to get a post is possible with the statement post = Post.find(id); to access its fields: post.title; or its relations: post.blog.
- Rails had a full active record implementation. It did not support search queries in database, while Grails and Django did.
- Grails had a full active record implementation. It supported searches and pagination. It can be seen an example of use in Myblog in this link.
- Django had a full active record implementation. It supported searches and pagination. It can be seen an example of use in Myblog in this link.
- CodeIgniter active record implementation lacked several features. There were no standard methods to retrieve an object from a database, or to find a record by an attribute, among others.
- Rails: it was really easy to implement and was full supported.
- Grails: Similar to Rails.
- Django: It was not supported.
- CodeIgniter: It was not supported.
- Follows the DRY Principle:
- Rails: Its structure followed greatly the DRY principle but the code generated was repeated in several controllers.
- Grails: Same as Rails.
- Django: It was the best framework in the comparison following this principle due to the fact that it used class-based views.
- CodeIgniter: It did not follow the principle as strongly as other web frameworks did. Most of the methods had to be written and they were usually very similar.
- Forms not binded to models: There are special cases where a form is presented in a website but it is not binded to a model. A contact form is an example. What is the approach of each framework to this problem?
- Rails used virtual attributes to define models which were not connected to a model. It was not well understood after development. It did not seem as clear as other solutions.
- Grails had a class that was called command objects and they served for this purpose.
- Django had a class called forms.
- CodeIgniter had a form library to help in this task.
- Convention over configuration
- Rails followed strictly the convention over configuration principle. It was positive to obtain a more concise code, as most of its part was assumed by the convention. But, if it was necessary to implement something different from the convention, for example not using REST convention, it increased complexity by implementing it.
- Grails followed less strictly convention, more configuration had to be done but it also helped when defining the personalized behaviour.
- Django followed this principle less strictly than Grails.
- CodeIgniter lacked following a convention, for example, there was no standard to call the models. It was decided to use the letter m in front of the name of the resource for naming it.
Comparing lines of code
Table 3 shows the total lines of source code for every implementation with each web framework. Grails called the models domains and Django, the controller views, but here it will be used the words model, controllers and views following the names used in the MVC pattern. It has been divided into four groups: views(it includes small functions to help called helpers and layouts), models, controllers(forms included) and routing files.
According to the results, Django presented the least amount of lines of code, followed by Rails and Grails and CodeIgniter. Django used the class-based views which implied less repetition and shorter code. Rails used code generation, but it generated a really short code which was possibly due to all the conventions assumed. Grails made generation, but it added more functionality in the code and was more verbose. Furthermore, it did not follow so many conventions as Rails. In CodeIgniter, it was necessary to write most of the functions, therefore, it had the biggest amount of lines of code.
Concerning the documentation,
Rails is a really well documented framework and has the greatest support from the community but learning how to use it requires a huge amount of time. Documentation could not be finished and many features could not be discovered throughout this implementation.
Grails documentation is not well organized, it is difficult to understand, it lacks examples and it has a poor support from the community. It seems to point to developers coming from Java frameworks, like Spring or others. Nevertheless, when it is understood, developing begins to be fast, as it has been proved in the developing times after the first module was implemented: second, third, and fourth module presented a similar implementation time in every web framework. It has more features than those which were discovered in this implementation.
Django documentation is as good as Rails, at least, and it has great support from the community. It has more features than those which were discovered in this implementation too.
CodeIgniter documentation could be completely read in less than the fixed time. Documentation was clear and concise. It was not necessary to look for questions because most of the times it was already known how to solve the problems. Mainly, because it was the programmer who had to create the methods.
Conerning the authentication system,
Rails was the framework which required the least amount of hours to implement this requirement despite the fact that the authentication system was built, it was not used any plugin(gem). It shows that, for an inexperienced programmer, it was faster having a tutorial than learning how to use the plugins in the other different frameworks. Being built by the programmer has the cons of being probably more insecure.
In Grails and Django the authentication systems had to be adapted, but the code was not easy to understand, neither how to customize it, it required more time. It is important to keep in mind that probably Grails and Django approaches are more secure as they underlie in the plugin implementation.
On the other hand, CodeIgniter offered a library whose code was copied into the application and adapted to it. It was easier to customize because it could be read the whole code, remove unnecessary parts and adapt others. Nevertheless, as it was copied into the project and fully adapted, it could have security problems as in Rails.
Concerning the developing common operations, CRUD,
Rails and Grails generated code are good approaches. Specially for an inexperienced programmer. It is more common that they will not know how to approach these problems, scaffold give a fast solution and it can be worked from there. Nevertheless, code is repeated several times in different controllers, it does not follow so strongly the DRY principle. As it was commented previously, Rails generated code was clearer than Grails, although Grails offered internationalization and version control.
Django approach with the class based views can be a bit harder to understand, but it is the best approach to follow the DRY principle and it gives the most concise code.
CodeIgniter does not offer generators,class-based views and even it does not have a complete ActiveRecord implementation, a library for accessing database records in an object oriented way. The framework helps with libraries and facilitates to follow the MVC pattern, but it has to be written several methods which were already supported in other frameworks. Due to this fact, it weakly follows the DRY principle and the Convention over Configuration.
Concerning the developing times,
Rails was the first framework to develop with. There were a lot to learn about the problem and web development in general, for example, differences between POST and GET verbs. Furthermore, when it was tried to modify the conventions, it increased complexity solving the problems. In Rails, in general, everything is going to be implemented, there will be a Rails manner to implement it and it requires the programmer to learn it.
Grails is the only framework whose implementation was not possible to be finished. It was almost finished but there were some functionalities left and some errors. The main problem with Grails was the documentation, the IDE, Groovy and Grails ToolSuite based on Eclipse, and the fact that the JVM had to be loaded for developing slowed down development speed.
Django was the first framework which presented less time to implement the full application. Reasons may be: experience from previous implementations, readable and understandable documentation and class-based views.
CodeIgniter is the only framework which required less time than fixed to read documentation and to implement the application. Nevertheless, it is the framework which less adequately follows the DRY and the Convention over Configuration principles. CodeIgniter does not have as many features as other frameworks in this comparison, therefore, it was not necessary to read the documentation all the time. Throughout the development, most of the times, it was not necessary to read how to use libraries and how they connect to each other, it simply could be programmed as it was needed. Therefore, it required the least amount of time, compared to others in this comparison.
In my opinion and summarize conclusion,
If a newbie programmer just wants a small web application get started fast, CodeIgniter is a good choice.
Rails, Django and Grails are frameworks which require a great effort to learn how to use them. Nevertheless, they are better prepared to support bigger applications, using them will result in a clearer, better organized, less repeated, easier to support code and to follow better a convention. Learning those frameworks is a time investment to obtain benefits in several months.
It is more common that bigger corporations will use Java, therefore Grails, based on Groovy, which is compiled into JVM, is more probable useful to find a job. Nevertheless, as it has been said, it is more difficult to learn it than others in this comparison.
Rails and Django are easier to learn, better documented and has strong support from the community. If you already know where you want to work or you want to become a web developer to implement your own projects, consider making the investment of time to learn to use any of those frameworks. I would choose between these two, mainly because of the support from the community.
My professional life now,
Since two month ago, I began to develop a web project with Rails. Why did I choose Rails?
- Support from the community.
- I know some people who began to work with Django and migrated to Rails.
And what really bothers me about Rails is that:
- It does not have bundle authentication system.
- It does not have class-based views or some way to avoid repetition in controllers. I specially miss this feature.
Are other frameworks I tested bad? No, it is not the case. Well, I think CodeIgniter is the worst option if you want to become a web/web-service developer in the long term. But other frameworks in this comparison are great, despite the fact that Grails has an awful documentation. In case you are interested in JVM framework, perhaps it would be better to take a look at Play!, it seems to be well supported. It is written in Scala, based on JVM.
What to say about this project?,
I have invested 800 hours in this project. That’s nearly 6 months of full-time job. It has been almost a year. Despite of that, I have a really low knowledge of each framework. Having a good level of knowledge about each framework would require more time. I have been able to make a comparison of ease of learning in any case.
So, a final question and the most important one:
Is it clearer now which web framework to choose?
Thanks for reading. Comments, criticism and sharing will be appreciated.