How to Design a Web Application: Software Architecture 101
Tags: architecture, design, microservices, codenewbie
Published: 2020-02-04 23:26:43

*Originally posted on [Educative.io](https://www.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](https://www.educative.io/courses/web-application-software-architecture-101). This is a useful course for anyone looking to strengthen their overall knowledge of software architecture.

Let’s dive in!

## What is software architecture?
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.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/eib1htrf0mzmuneqcxpr.jpg)

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.


## Why is software architecture 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.


## The difference between software architecture and software design
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](https://www.educative.io/courses/software-design-patterns-best-practices).

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](https://www.educative.io/blog/the-7-most-important-software-design-patterns).

## Software architecture patterns
### Client-server
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.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/g7rvw6dd1q5qg0zuetxe.jpeg)

### Peer-to-peer
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.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/togxlje8najrdwb6etru.jpeg)

### Model-View-Controller (MVC)
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.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1ni6qx5c5ij57hxeh5cf.png)

### Microservices
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.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/nm7ms0ce70ett31yw71b.jpeg)

### Event driven
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.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ynfth6oaprzk543ppdhw.jpeg)

### Layered
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

### Hexagonal
The architecture consists of three components:

* Ports
* Adapters
* 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.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/zi3bzygq756jupfmwxdz.jpeg)

## How to decide on the number of tiers your app should have
### Single tier application
**Pros:**

* No network latency
* Data is quickly and easily available
* Data is not transferred over a network which ensures data safety

**Cons:**

* 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

### Two-tier application
**Pros:**

* 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.

**Cons:**

* 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.

### Three-tier application
**Pros:**

* 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.

**Cons:**

* 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.

### N-Tier application
**Pros:**

* 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

**Cons:**

* Due to the componentization of the tiers, the complex structure is difficult to implement or maintain

### Conclusion
* 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.

## Horizontal or vertical scaling… Which is right for my app?
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.**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7enieqd0bn8qvk7xvscx.jpeg)

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.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/fcutuygeu8j95izjjp7j.jpeg)

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](http://highscalability.com/).

## Monolith or Microservice?
Let’s explore when you should choose one over the other.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/u221x0bb2q18b385wq1t.png)

### When to use monolithic architecture
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](https://engineering.linkedin.com/architecture/brief-history-scaling-linkedin).

### When to use microservice architecture
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.

## When should you use NoSQL or SQL?
### When to pick a SQL database?
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:

#### Transactions & Data Consistency
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.

#### Storing Relationships
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:**

* MySQL
* Microsoft SQL Server
* PostgreSQL
* MariaDB

### When to pick a NoSQL database
Here are a few reasons why you’d want to pick a NoSQL database:

#### Handling A Large Number Of Read Write Operations
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.


#### Running data analytics
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:**

* MongoDB
* Redis
* Cassandra
* HBASE

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](https://www.educative.io/courses/definitive-guide-to-mongodb).

## Picking the right technology for the job
### Real time data interaction
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](https://pypi.org/project/tornado/3.2.1/). If you are working in the Java Ecosystem you can look into Spring Reactor, Play, [Akka.io](https://akka.io/).


### Peer-to-peer web application
If you intend to build a peer to peer web app, for instance, a P2P distributed search engine or a P2P Live TV radio service, something similar to LiveStation by Microsoft, then you’ll want to look into JavaScript, protocols like DAT, IPFS. Checkout [FreedomJS](https://www.freedomjs.org/), it’s a framework for building P2P web apps that work in modern web browsers.


### CRUD-based Regular Application
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.


### Simple, small scale applications
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](https://www.educative.io/courses/learn-php-from-scratch) 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.


### CPU and memory intensive applications
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](https://www.educative.io/courses/learn-cpp-from-scratch).

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](https://www.educative.io/courses/introduction-to-programming-in-go).

Julia is a dynamically programmed language built for high performance & running computations & numerical analytics.

Learn [C++](https://www.educative.io/courses/learn-cpp-from-scratch), [Rust](https://www.educative.io/courses/learn-rust-from-scratch), [Scala](https://www.educative.io/courses/learn-scala-from-scratch), and [Java](https://www.educative.io/courses/learn-java-from-scratch) for free today.

## How to become a software architect?
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](https://www.educative.io/courses/web-application-software-architecture-101) is a great place to start learning the best practices for designing and implementing web applications.

## Where to go from here?
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](https://www.educative.io/courses/web-application-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.**

Happy learning!