The Software Architecture Handbook
The Software Architecture Handbook
Handbook
German
Cocca
Hi everyone! In this handbook you're going
to learn about the vast, intricate field that is
Software Architecture.
This is a field that I found both confusing and
intimidating when I was first starting my journey into
coding. So I'll try and spare you the confusion.
Table of Contents
What is software architecture?
Important software architecture concepts to know
What's the Client-Server model?
What are APIs?
What is Modularity?
What's your infrastructure like?
Monolithic Architecture
Microservices Architecture
What is back end for front-end (BFF)?
How to use load balancers and horizontal scaling
Where your infrastructure lives
On premise hosting
Traditional server providers
Hosting on the Cloud
Traditional
Elastic
Serverless
Lots of other services
Different folder structures to know
All in one place folder structure
Layers folder structure
MVC folder structure
Conclusion
What is software architecture?
According to this source:
The software architecture of a system represents the
design decisions related to overall system structure and
behavior.
That's quite generic, right? Absolutely. And that's
exactly what used to confuse me so much when
researching about software architecture. It's a topic that
encompasses a lot and the term is used to talk about
many different things.
Microservices Architecture
So turns out Notflix is totally rocking it. We just released
the latest season of "Stranger thugs", which is an
awesome science fiction series about teenage rappers,
and our movie "Agent 404" (about a secret agent that
infiltrates in a company simulating being a senior
programmer but actually doesn't know a thing about
code) is breaking all records...
On-Premise Hosting
On premise means you own the hardware in which your
app is running. In the past this used to be the most
traditional way of hosting applications. Companies used
to have dedicated rooms for servers to be in and teams
dedicated to the set up and maintenance of the
hardware.
Traditional
The first way is to use them in a similar way you'd use a
traditional server provider. You select the kind of
hardware you want and pay exactly for that on a
monthly basis.
Elastic
The second way is to take advantage of the "elastic"
computing offered by most providers. "Elastic" means
that the hardware capacity of your application will
automatically grow or shrink depending on the usage
your app has.
For example, you could start out with a server that has
8gb of RAM and 500gb of disk space. If your server
starts getting more and more request and these
capacities are no longer enough to provide good
performance, the system can automatically perform
vertical or horizontal scaling.
Serverless
Another way in which you can use cloud computing is
with a serverless architecture.
Following this pattern, you wont have a server that
receives all requests and responds to them. Instead
you'll have individual functions mapped to an access
point (similar to an API endpoint).
Within our app.js file we'll have our tiny server, our
mock DB, and two endpoints:
// App.js
const express = require('express');
/* Routes */
app.get('/rabbits', (req, res) => {
res.json(db)
})
http://localhost:7070/rabbits
# [
# {
# "id": 1,
# "name": "John"
# },
# {
# "id": 2,
# "name": "Jane"
# },
# {
# "id": 3,
# "name": "Joe"
# },
# ....
# ]
###
http://localhost:7070/rabbits/1
# {
# "id": 2,
# "name": "Jane"
# }
So what's the problem with this? Nothing, actually, it
works just fine. The problem will only arise when the
codebase gets bigger and more complex, and we start
adding new features to our API.
/* Routes */
app.use('/rabbits', rabbitRoutes)
router.get('/', listRabbits)
router.get('/:id', getRabbit)
router.delete('/:id', deleteRabbit)
module.exports = router
rabbits.controllers.js holds the logic corresponding to
each endpoint. Here is where we program what the
function should take as input, what process should it
perform and what should it return. 😉 Moreover, each
controller links to the corresponding model function
(which will perform database related operations).
// rabbits.controllers.js
const { getAllItems, getItem, editItem, addItem, deleteItem } =
require('../models/rabbits.models')
const listRabbits = (req, res) => {
try {
const resp = getAllItems()
res.status(200).send(resp)
} catch (err) {
res.status(500).send(err)
}
}
} catch (err) {
res.status(500).send(err)
}
}
module.exports = db
As we can see, there're a lot more folders and files
under this architecture. But as a consequence, our
codebase is much more structured and clearly
organized. Everything has its own place and the
communication between different files is clearly
defined.
const rabbitControllers =
require("./rabbits/controllers/rabbits.controllers")
// Ejs config
app.set("view engine", "ejs")
app.set('views', path.join(__dirname, './rabbits/views'))
/* Controllers */
app.use("/rabbits", rabbitControllers)
} catch (err) {
res.status(500).send(err)
}
})
} catch (err) {
res.status(500).send(err)
}
})
} catch (err) {
res.status(500).send(err)
}
})
} catch (err) {
res.status(500).send(err)
}
})
module.exports = router
Finally, in the view files we take the variable received
as parameter and render it as HTML.
<!-- Rabbits view -->
<!DOCTYPE html>
<html lang="en">
<body>
<header>All rabbits</header>
<main>
<ul>
<% rabbits.forEach(function(rabbit) { %>
<li>
Id: <%= rabbit.id %>
Name: <%= rabbit.name %>
</li>
<% }) %>
</ul>
</main>
</body>
</html>
<!-- Rabbit view -->
<!DOCTYPE html>
<html lang="en">
<body>
<header>Rabbit view</header>
<main>
<p>
Id: <%= rabbit.id %>
Name: <%= rabbit.name %>
</p>
</main>
</body>
</html>
Now we can go to our browser,
hit http://localhost:7070/rabbits and get:
Or [http://localhost:7070/rabbits](http://localhost:7070/
rabbits)/2 and get:
And that's MVC!
Conclusion
I hope all these examples helped you wrap your head
around what are we talking about when we mention
"architecture" within the software world.
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT
German
Cocca
I'm a full stack developer (typescript | react | react
native | node | express) and computer science student.
In this blog I write about the things I learn along my
path to becoming the best developer I can be.