Originally posted on Educative.io
So you’ve embarked on the entrepreneurial journey to build your own web application. You’ve got the idea in place, but the significance of getting the architecture right is extremely important.
In this post we’ll walk through these key areas:
- What is software architecture
- Why is software architecture important
- The difference between software architecture and software design
- Software architecture patterns
- How to decide on the number of tiers your app should have
- Horizontal or vertical scaling… Which is right for my app?
- Monolith or Microservice?
- When should you use NoSQL or SQL?
- Picking the right technology for the job
- How to become a software architect
- Where to go from here
The goal of this post is to give you a solid understanding of web architecture, the concepts involved, and how to pick the right architecture and technology when designing your app. So by the end of this post, when you go to design an application from the bare bones you won’t be sitting in the dark anymore.
If you’re looking for a complete course on web application and software architecture, I recommend checking out Web Application and Software Architecture 101. This is a useful course for anyone looking to strengthen their overall knowledge of software architecture.
Let’s dive in!
Software architecture of a system describes its major components, their relationships, and how they interact with each other.
It essentially serves as a blueprint. It provides an abstraction to manage the system complexity and establish communication and coordination among components.
Here are some key points:
- The architecture helps define a solution to meet all the technical and operational requirements, with the common goal of optimizing for performance and security.
- Designing the architecture involves the intersection of the organization’s needs as well as the needs of the development team. Each decision can have a considerable impact on quality, maintainability, performance, etc.
One of my favorite definitions of software architecture came from Ralph Johnson, co-author of Design Patterns: Elements of Reusable Object-Oriented Software. He stated that:
It's the decisions you wish you could get right early in a project.
So with that said, let’s move on to why software architecture is important.
The key element in successfully creating anything is getting the base right. Now whether it is constructing a building or making a pizza. If we don’t get the base right, we have to start over; there is no other way around.
Building a web application is no different. The architecture is its base and has to be carefully thought out to avoid any major design changes & code refactoring at a later point in time. Many engineers will tell you that you don’t want to delve into re-designing stuff. It eats up your time like a black hole. It has the potential to push your shipping date further down the calendar by months, if not longer. And that’s not even bringing up the wastage of engineering and financial resources which is caused due to this.
It also depends on what stage of the development process we hit an impasse due to the hasty decisions taken during the initial design phases. So, before we even touch the code and get our hands dirty, we have to make the underlying architecture right.
Though software development is an iterative and evolutionary process, we don’t always get things perfect at the first go. Still, this can’t be an excuse for not doing our homework.
There is often confusion between software design and architecture so we’ll break this down.
Software architecture is used to define the skeleton and the high-level components of a system, and how they will all work together. For example, do you need serverless architecture which splits the application into two components: BaaS (backend-as-a-service) and FaaS (functions-as-a-service)? Or do you need something like a microservice architecture where the different features/tasks are split into separate respective modules/codebases?
Choosing an architecture will determine how you deal with performance, fault tolerance, scalability, and reliability.
Software design is responsible for the code level design such as, what each module is doing, the classes scope, and the functions purposes, etc. When used strategically, they can make a programmer significantly more efficient by allowing them to avoid reinventing the wheel, instead using methods refined by others already. They also provide a useful common language to conceptualize repeated problems and solutions when discussing with others or managing code in larger teams. Start leveraging software design patterns in your code with this helpful course: Software Design Patterns: Best Practices for Software Developers.
Here is a good article on understanding the importance of software design and the tried and true patterns that developers frequently use: The 7 most important software design patterns.
The architecture works on a request-response model. The client sends the request to the server for information & the server responds with it.
Every website you browse, be it a Wordpress blog or a web application like Facebook, Twitter or your banking app is built on the client-server architecture.
A P2P network is a network in which computers also known as nodes can communicate with each other without the need of a central server. The absence of a central server rules out the possibility of a single point of failure. All the computers in the network have equal rights. A node acts as a seeder and a leecher at the same time. So, even if some of the computers/nodes go down, the network & the communication is still up.
P2P is the base of blockchain technology.
The MVC architecture is a software architectural pattern in which the application logic is divided into three components on the basis of functionality. These components are called: Models - represent how data is stored in the database Views - the components that are visible to the user, such as an output or a GUI Controllers - the components that act as an interface between models and views
The MVC architecture is used not only for desktop applications but also for mobile and web applications.
In a microservice architecture, different features/tasks are split into separate respective modules/codebases which work in conjunction with each other forming a large service as a whole.
This particular architecture facilitates easier & cleaner app maintenance, feature development, testing & deployment in comparison to a monolithic architecture.
Non-blocking architecture is also known as the Reactive or the Event-driven architecture. Event-driven architectures are pretty popular in the modern web application development.
They are capable of handling a big number of concurrent connections with minimal resource consumption. Modern applications need a fully asynchronous model to scale. These modern web frameworks provide more reliable behavior in a distributed environment.
This pattern can be used to structure programs that can be decomposed into groups of subtasks, each of which is at a particular level of abstraction. Each layer provides services to the next higher layer.
Here are the most common layers:
- Presentation layer
- Application layer
- Business logic layer
- Data access layer
The architecture consists of three components:
- Domain The focus of this architecture is to make different components of the application independent, loosely coupled & easy to test.
The architectural pattern holds the domain at its core, that’s the business logic. On the outside, the outer layer has Ports & Adapters. Ports act like an API, as an interface. All the input to the app goes through the interface.
- No network latency
- Data is quickly and easily available
- Data is not transferred over a network which ensures data safety
- Little control over the application; hard to implement new features or code changes once it’s shipped
- Testing has to be extremely thorough with minimal room for mistakes
- Single tier applications are vulnerable to being tweaked or reverse engineered
- Fewer network calls since the code and UI are in the same machine
- Database server and business logic is physically close, which offers higher performance.
- Since the client holds most of the application logic, problems arise in controlling the software version and re-distributing new versions.
- Lacks scalability as it supports only a limited number of users. When multiple client requests increases, application performance can slow down due to the fact that clients necessitate separate connections and CPU memory to proceed.
- Since the application logic is coupled with the client, it’s difficult to re-use logic.
- Data corruption through client applications can be eliminated as the data passed in the middle tier for database updations ensures its validity
- The placement of the business logic on a centralized server makes the data more secure
- Due to the distributed deployment of application servers, scalability of the system is enhanced since a separate connection from each client is not required whereas connections from few application servers are sufficient.
- Usually more effort should be enforced when creating 3-tier applications as the communication points are increased (client to middle tier to server, instead of directly client to server) and the performance increased by tools like Visual Basic, PowerBuilder, Delphi will be reduced.
- All the pros of three-tier architecture
- The performance is increased due to off-load from the database tier and the client tier, enabling it to suit medium to high volume industries
- Due to the componentization of the tiers, the complex structure is difficult to implement or maintain
- You should choose a single tier architecture when you do not want any network latency
- Choose a two tier application when you need to minimize network latency and you need more control of data within your application
- You should choose a three tier architecture when you need control over the code/business logic of your application & want it to be secure, and you need control over data in your application.
- You should choose a N tier architecture when you need your application to scale and handle large amounts of data.
If your app is a utility or a tool which is expected to receive minimal consistent traffic, it may not be mission-critical. For instance, an internal tool of an organization or something similar. Why bother hosting it in a distributed environment? A single server is enough to manage the traffic, so you could go with vertical scaling when you know that the traffic load would not increase significantly.
If your app is a public-facing social app like a social network, a fitness app or something similar, then the traffic is expected to spike exponentially in the near future. In this case, both high availability and horizontal scalability is important to you.
Build to deploy it on the cloud & always have horizontal scalability in mind right from the start. Here is a good website for learning more about scalability.
Let’s explore when you should choose one over the other.
Monolithic applications fit best for use cases where the requirements are pretty simple, the app is expected to handle a limited amount of traffic. One example of this is an internal tax calculation app of an organization or a similar open public tool.
These are the use cases where the business is certain that there won’t be an exponential growth in the user base and the traffic over time.
There are also instances where the dev teams decide to start with a monolithic architecture and later scale out to a distributed microservices architecture.
This helps them deal with the complexity of the application step by step as and when required. This is exactly what LinkedIn did.
The microservice architecture fits best for complex use cases and for apps which expect traffic to increase exponentially in future like a fancy social network application.
A typical social networking application has various components such as messaging, real-time chat, LIVE video streaming, image uploads, Like, Share feature etc.
In this scenario, I would suggest developing each component separately keeping the Single Responsibility and the Separation of Concerns principle in mind.
Writing every feature in a single codebase would take no time in becoming a mess.
So, by now, in the context of monolithic and microservices, we have gone through three approaches:
- Picking a monolithic architecture
- Picking a microservice architecture
- Starting with a monolithic architecture and then later scale out into a microservice architecture.
Picking a monolithic or a microservice architecture largely depends on our use case. I’ll suggest, keep things simple, have a thorough understanding of the requirements. Get the lay of the land, build something only when you need it & keep evolving the code iteratively. This is the right way to go.
If you are writing a stock trading, banking or a Finance-based app or you need to store a lot of relationships, for instance, when writing a social networking app like Facebook, then you should pick a relational database. Here’s why:
If you are writing software which has anything to do with money or numbers, that makes transactions, ACID, data consistency super important to you. Relational DBs shine when it comes to transactions & data consistency. They comply with the ACID rule, have been around for ages & are battle-tested.
If your data has a lot of relationships like which friends of yours live in a particular city? Which of your friend already ate at the restaurant you plan to visit today? etc. There is nothing better than a relational database for storing this kind of data.
Relational databases are built to store relationships. They have been tried & tested & are used by big guns in the industry like Facebook as the main user-facing database.
Popular relational databases:
- Microsoft SQL Server
Here are a few reasons why you’d want to pick a NoSQL database:
Look towards NoSQL databases when you need to scale fast. For example, when there are a large number of read-write operations on your website and when dealing with a large amount of data, NoSQL databases fit best in these scenarios. Since they have the ability to add nodes on the fly, they can handle more concurrent traffic and large amounts of data with minimal latency.
NoSQL databases also fit best for data analytics use cases, where we have to deal with an influx of massive amounts of data.
Popular NoSQL databases:
If you’re curious about trying a NoSQL database like MongoDB then I highly suggest checking out Nikola Zivkovic’s course, The Definitive Guide to MongoDB.
If you are building an app that needs:
- To interact with the backend server in real-time, such as a messaging application, or an audio-video streaming app like Spotify, Netflix etc.
- A persistent connection between the client and server, and a non-blocking technology on the back-end.
Then some of the popular technologies which enable you to write these apps are NodeJS, and the popular Python framework known as Tornado. If you are working in the Java Ecosystem you can look into Spring Reactor, Play, Akka.io.
If you have simple use cases such as a regular CRUD-based app, then some of the technologies which you can use are: Spring MVC, Python Django, Ruby on Rails, PHP Laravel, ASP .NET MVC.
If you intend to write an app which doesn’t involve much complexity like a blog, a simple online form, simple apps which integrate with social media that run within the IFrame of the portal, then you can pick PHP. Learn PHP for free today.
You can also consider other web frameworks like Spring boot, Ruby on Rails, which cut down the verbosity, configuration, development time by notches & facilitate rapid development. But PHP hosting will cost much less in comparison to hosting other technologies. It is ideal for very simple use cases.
Do you need to run CPU Intensive, Memory Intensive, heavy computational tasks on the backend such as Big Data Processing, Parallel Processing, Running Monitoring & Analytics on quite a large amount of data?
Regular web frameworks & scripting languages are not meant for number crunching. Tech commonly used in the industry to write performant, scalable, distributed systems is C++. It has features that facilitate low-level memory manipulation, providing more control over memory to the developers when writing distributed systems. Majority of the cryptocurrencies are written using this language. Here’s a great course to Learn C++ for free.
Rust is a programming language similar to C++. It is built for high performance and safe concurrency. It’s gaining a lot of popularity lately amongst the developer circles. Java, Scala & Erlang are also a good pick. Most of the large scale enterprise systems are written in Java.
Go is a programming language by Google to write apps for multi-core machines & handling a large amount of data. Here’s how you can get started with Go development.
Julia is a dynamically programmed language built for high performance & running computations & numerical analytics.
If this all sounds interesting, then you may aspire to be a software architect. But where do you start? Well, it’s extremely uncommon for someone to start out as a software architect, so most software engineers work for a few years before they take on designing architecture.
One of the best ways to become familiar with software architecture is by designing your own web applications. This will force you to think through all the different aspects of your application, from load balancing, message queueing, stream processing, caching and more. Once you start to understand how these concepts fit into your app, you’ll be well on your way to becoming a software architect.
As an aspiring software architect, you need to constantly expand your knowledge and stay on top of the latest industry trends. You may start by learning one or more programming languages, work as a software developer, and gradually make your way.
Even though you can’t get a software architect degree in college, there are other courses that you may find useful. Web Application and Software Architecture 101 is a great place to start learning the best practices for designing and implementing web applications.
While there was a lot covered in this post, we’ve merely touched the surface on this topic. We still have yet to explore REST APIs, high availability, and CAP theorem.
If you’d like a deep dive into software architecture, I highly recommend Web Application and Software Architecture 101. It walks you step by step through different components & concepts involved when designing the architecture of a web application.
You’ll learn about various architectural styles such as the client-server, peer to peer decentralized architecture, microservices, the fundamentals of data flow in a web application, different layers involved, concepts like scalability, high availability and much more.
Additionally, you’ll go through the techniques of picking the right architecture and the technology stack to implement your use case. You'll walk you through different use cases which will help you gain an insight into what technology & architecture fits best for a certain use case when writing a web application. You’ll come to understand the technology trade-offs involved.
If you are a beginner just starting your career in software development, this course will help you a lot. It will also help you with the software engineering interviews, especially for the full stack developer positions.