This article is the second part of the series Creating the modern developer stack template. I definitely recommend reading the first one before this to get more context.
Introduction
Hello folks,
Let's start with the piece of the stack that is sitting all the way back, the database. There exist two primary types of database, SQL and NoSQL. For each of those types, there are dozens of different alternatives. To cut down my research in more than half, I will solely focus on databases from the NoSQL family. As mentioned in the first article, I will only investigate open source databases. I will be looking for ease of use; so how easy it is to get started with this database and the quality of the documentation. Popularity is another big factor that goes hands down with the ease of use as you will be able to find solutions to all the common problems a newbie can have. Performance is also something to keep in mind. Still, it will have lesser importance than the 2 previous points as I believe most databases nowadays will provide decent enough performance for most of the use cases. Thus, you don't want to sacrifice development speed for your database's very marginal performance gain.
Comparisons
MongoDB
Pros:
- Easy to set up with adequate support in node
- Advanced query language supported in the form of JSON
- Easy to scale
- Amazing documentation
- Wide community support
- Compound indexes
- Transaction support
Cons:
- Data size because each document store every field names
- Joining collections together is tedious
rxdb
Pros:
- Good documentation
- Uses CouchDB under the hood
- Subscription to events (real-time)
- Offline support
Cons:
- Not used in many projects
- Doesn't provide enterprise-grade support
- Was created only four years ago (2016)
Arangodb
Pros:
- Uses SQL like query language
- Can store multi-model documents, graphs, key-value
- Supports elastic scalability
- Very fast
Cons:
- Not used in many projects
- Has a high memory usage
Neo4j
Pros:
- Very fast for handling relationships as it is a graph database
- Supports ACID transactions
Cons:
- Hard to follow the documentation
- You need to define schemas of your data at the database level
- The javascript driver only has one year of life (2019)
There exist, of course, many other databases in the NoSQL realm, although I can't cover them all. I've selected these databases based on this query on GitHub, and I chose the top 4. After identifying some pros and cons, I noticed that each database has different use cases in mind. If you want a real-time database, use rxdb, for complex relationships: Neo4j, general-purpose with broad community support: MongoDB and the one that tries to mix the capabilities of both MongoDB and Neo4j, go with ArangoDB. Since I'm trying to build a general-purpose template, I think going with the database that has the most significant community will alleviate some of the missing features it might miss through community projects.
Implementation in Stator
I'm a massive advocate of monorepos, but one of the most commonly cited critics of them is the build time and testing time, which gets annihilated by NX. NX uses an intelligent build system with distributed caching to solve those issues. It also allows you to generate pre-configured projects to add missing pieces to your stack easily.
Enough said about monorepos, let's get back to our database. To ensure ease of use, let's create a docker-compose.yml
file:
version: '3.6'
services:
database:
image: mongo:4.2.3-bionic
container_name: stator-mongo
ports:
- 27017:27017
environment:
- MONGO_INITDB_DATABASE=stator
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=admin
volumes:
# seeding scripts (optional)
- ./mongo-entrypoint:/docker-entrypoint-initdb.d
# named volumes
- mongodb:/data/db
- mongoconfig:/data/configdb
volumes:
mongodb:
mongoconfig:
Using docker-compose up
, we can easily launch our database. One advantage of using docker is that we ensure all the developers working on the project will be using the same version. Running this command will launch your mongo database seeded with a user [stator
] with password [secret
], which you can use to connect to the database. A default database [stator
] will also be created for you. Note that all your database data will be persisted unless you intentionally remove the docker volume. If you would also like to see how the data seeding works, please refer to this.
Choosing the perfect database is a daunting task as it will be one of the core pieces of your architecture. Hopefully, this article helped you shed some light on which database you should use based on your use case. This now completes the deepest layer of my open-source template on stator.
You can read the next article here.