
Persistence layer
The first decision that needs to be made when designing a persistence layer is to decide on the type of the data store. The data store could be a relational SQL database such as Microsoft SQL or MySQL, among others. Alternatively, it can be a NoSQL store, such as MongoDB, or Apache Cassandra, among others.
In an efficient and complex production environment, the code needs to be capable of switching from one data store to another without too much refactoring. Consider the following example—you build a number of microservices for a start-up that relies on MongoDB as the data store; then, as the organization changes, you decide that AWS cloud-based DynamoDB would make a better data store for the microservices. If the code doesn't allow easily unplugging MySQL, then plugging a MongoDB layer in its place, tons of code refactoring will be needed in our microservices. In Go, we will achieve that flexible design using interfaces.
It is worth mentioning that in microservices architectures, different services can require different types of datastores, so it is normal for one microservice to use MongoDB, whereas another service would use MySQL.
Let's assume that we are building a persistence layer for the events microservice. Based on what we have covered so far, the events microservice persistence layer would primarily care about three things:
- Adding a new event to the databases
- Finding an event by ID
- Finding an event by name
To achieve flexible code design, we would need the preceding three functionalities to be defined in an interface. It would look like this:
type DatabaseHandler interface {
AddEvent(Event) ([]byte, error)
FindEvent([]byte) (Event, error)
FindEventByName(string) (Event, error)
FindAllAvailableEvents() ([]Event, error)
}
The Event datatype is a struct type that represents the data of an event, such as the event name, location, time, among other things. For now, let's focus on the DatabaseHandler interface. It supports four methods that represent the required tasks from the events service persistence layer. We can then create numerous concrete implementations from this interface. One implementation can support MongoDB, while another can support the cloud-native AWS DynamoDB database.
We'll cover AWS DynamoDB in a later chapter. In this chapter, the focus will be on MongoDB.