One of the most debated topics in recent years is, which backend framework should I choose. And there really is no answer, there is no framework that is better than all, they all have their pros and cons. It all depends a lot on the requirement, the domain of the problem or the platform to be developed.
Another false premise that we usually find is that we are inclined to choose a framework because of its popularity when popular does not necessarily mean better, it all depends on the need. We must remove the concept that sometimes we ourselves always want to recommend our preferred framework no matter the problem. We recommend everyone to use our preferred technology of the moment as a panacea to develop any application, without even really understanding what the need is. This is a practice that we have to learn to leave in the past, remove that chip.
Every framework has its trade-off, absolutely all have their points for and against, whoever says otherwise is because they have never encountered problems, but it does not mean that they are non-existent. But then, under what parameters should we guide ourselves when choosing a Backend framework.
We can say that there are several parameters:
- Convention vs Configuration
- Performance / Speed
- Programming language
To make this point into account when making our choice, we have to understand what this particular term refers to.
As the word implies, convention is a standardized, generalized practice, generally adopted by a community. When we translate this concept into backend frameworks domain, it refers to frameworks that have standard and predefined functionalities, where the developer does not need to implement them. For example, frameworks that come with session management, pre-defined middleware, authentication services, routers, Model-View-Controller management, among others. These are generally the most popular frameworks, such as Django, Rails, Lavarel.
Now, the configuration ones, contrary to the frameworks by convention, are the ones that leave most of the configuration in the hands of the developers, generally, they do not have many defined "conventions" implemented, but rather leave those implementations to the developers. They may not have authentication modules, predefined database management interface, among others. Control belongs entirely to the user. An example of this can be Tornado with Python, Fasthttp with Go, or Express with NodeJS.
Usually, this difference can also be read in some other communities like full-stack vs rest frameworks.
Now, to make a decision, as we mentioned before, we must understand the trade-off of each option, the points for or against it.
- They are very productive frameworks, by bringing many functionalities already pre-defined or implemented, the development team does not need to waste time developing them.
- If it is a widely used framework, they are generally supported by an extensive and broad community that surely guides or drives its development to follow the best practices in the industry. This is very positive, especially for teams that do not have as much knowledge in that framework.
- Now, those pre-defined features usually come packaged in black-boxes. This refers to parts of the code or functionalities that are obfuscated or hidden from the developer. As the famous phrase says, it works by magic. But, why this can have a negative impact, simple since if we want to change the way these standard modules work, it could represent a challenge since it implies modifying the default behavior of the framework and this couldn't be a trivial task.
- It is much more difficult to debug. Because any found error may reside inside those black boxes.
- Extra security considerations may be required since those kinds of frameworks are so well known for both good and bad, the possible ways to attack them could be huge. But nothing that a good security policy doesn't fix, right?
- Due to their nature, they can be adapted to many problems or needs, since as the configuration is left to the user, the developer can implement more customized flows, which would be challenging using a typical convention framework.
- Easier to debug as they have fewer black boxes than a framework by convention.
- In general, they are more efficient, since they can be used with the minimum required, avoiding overloading, in general, many times we try to kill a fly with a gun, we want to solve a small problem with a framework where we do not use even 50 % of its pre-defined functionalities.
- Clearly, this type of frameworks, depending on the required functionality, can cause the development time to be a little longer for standardized things, this can impact the productivity of the team.
- For new programmers, depending on the type of platform that is being developed, it can represent certain complexity problems, since they will not have those guidelines that a framework by convention may have. Therefore, developers could encounter some system designing challenges. For example, if the framework does not have a defined structure for the files, in the end, this can make the project end up being spaghetti if good design decisions are not made.
So, we can conclude that if you want to implement standard functionalities, such services with database connection, authentication, CRUD management, among others, a framework by convention would be generally better. If, on the contrary, we need to implement an API with very specific functionality to our business that needs to escalate very quickly, a better approach could be using a framework by configuration. As we'll see in the next section, those frameworks generally tend to favor performance. To illustrate better, if we try to implement web-sockets in C, it will be much more difficult if we use NodeJS instead.
If productivity is a very key metric in your current work environment, as could be in a startup, the best option is a framework by convention, bearing in mind that development times would be shorter. In addition, using the most popular frameworks could guarantee that you won't have issues finding developers. Sometimes, this would impact development time and its associated costs.
Frameworks by convention
- Ruby On Rails(Ruby)
- Cake PHP
Frameworks by configuration
- NextJS(NodeJS) It's a mix between Configuration and Convention.
These metrics are one of the most important but most difficult to measure because conceptually the meaning of performance/speed lies in different aspects. But to facilitate the conceptualization exercise, we can establish it as the impact of a request on system resources such as memory, CPU, disk, among others.
Another important point is the capacity for concurrent requests that can be handled in a certain period of time.
Finally, although not necessarily every application needs a database, it is also necessary to understand how important the relationship between our framework and it will be. Since this can greatly impact performance depending on our needs.
Now, how to choose based on performance or speed, for this, it is important to understand the number of requests that our framework will face. It is not the same to have to accept thousands of requests per second, per minute, or per hour. Therefore, before choosing a framework, it is good to review certain benchmarks (I recommend this of how it behaves under the number of requests that we will need to handle. For example, if we need to build an API to receive thousands of data from many sensors every second, maybe a framework like Django or Rails would not be the best option, it may be better to opt for a framework that handles concurrency much better like fasthttp with Go. If we need to make a hotel reservation system, maybe something like Lavarel, Rails, Django can be better due to their robustness, and tanking in count ultra-performance is not our main goal.
Here you can check a well-known framework benchmark
As you can see, if you need to handle large amounts of requests per second, traditional frameworks, do not perform well. But of course, we must take into account the domain of the problem, because it may be that the vast majority of developers do not need to handle such a high volume of concurrency. If you need more information about backend framework benchmark, you can check it out here
Regarding database connections and how the framework interacts with them is very important, currently, many frameworks have built-in ORM (Object-Relational-Mapping), which is an interface that allows queries on relational databases, but at the cost of adding extra layers, impacting the connection and queries performance. Therefore, if our application requires making very complex queries or maintaining many connections simultaneously, it's preferable to use a framework that gives you more freedom and that does not have so many layers.
Here we can see a benchmark making rest API calls that in turn, each makes 20 queries to the database in instances c3.large (R10) / m1.large (R1 to R9) EC2 instances in AWS.
As you can notice, the same thing happens as with the previous graphic, we can see big differences between conventional frameworks and most specific ones, but not necessarily that difference can be translated into positives points, because, trying to find a Rust developer could be more complicated than a spring or rails developer. Maybe if we want to implement a reservation system, with Rust it will become extremely complex, because we would need to re-invent the wheel. So we can see the trade-off: productivity vs performance.
This is an important point when deciding which framework to use, since having a larger community implies that it has better support or documentation. Also, possible errors that the programmer may face, could have been documented/resolved by others.
Web development is already a widely studied topic, therefore, we see that many frameworks that opt for a convention, follow global standards, their structure or way of working is very similar, therefore, when choosing a framework we can really reduce it to choose which programming language we want to use and to make that decision there are several variables to take into account, complexity or learning curve, community, popularity, performance, domain or purpose.
To give an example in another context, if we need to develop a hardware controller, we need to use a language as close as to machine language like C and not Python which is a scripting language. But if, on the other hand, we want to implement high-level functionalities, a high-level language is better. If we want to handle concurrency, Perl or Earlang would be a good fit.
I think there are two main points that can help us make a decision and that is performance vs. productivity. In general, if you are in a startup, doing an MVP or a standard product, it's best to choose a framework based on its productivity, predefined features, and standards. This will have an impact on both monetary and human resources. In this case, I would lean towards a convention framework.
In general, companies like Facebook, Google, Twitter, among others, productivity is not a problem, they have many resources and hundreds of software engineers, they can even afford to build their own frameworks, React is a perfect example, which began as a tool within Facebook and has now become a global standard. So, if you have a large team, time, a problem domain where performance is critical, I would lean towards a framework that gives you all the flexibility possible, which is generated by a configuration type.
I would like to leave a recommendation aside, never say use always my preferred framework or preferred programming language. Perfection in programming does not exist, nor will it exist. We can detect high seniority in software engineers, if when you ask what is the best programming language? the first word you answer is it depends.
If you like my content or it was helpful, you can motivate me to write more content by buying me a coffee
Feel free to ask me anything in the comments or if you have any suggestion about how to select a framework, let me know it.
I made a youtube video of this post. Feel free to subscribe, I create content about full-stack technologies.
Also, feel free to follow me here in dev.to get notifications as soon as a new post is released.