2.1 Data modeling
In this lesson, we'll take a closer look at some of the implementation
details of the Issue Tracker application, and discuss some of the
design decisions that were made in its development thus far. We'll learn
about the Entity-relationship model and how it applies to abstractions
used throughout the software stack. From there, we'll briefly discuss
relational database best practices and how this translates to user-facing
API design.
Entity-relationship model
The Entity-relationship model (ER model) is a generic model that
defines the relationships between entities, where an entity can be
defined as a single instance of some thing, such as an issue in the case
of the Issue Tracker.
The ER model is used to enforce a separation of concerns and applies it to the data you persist in your database of choice, the abstractions your code interacts with in its business logic, as well as the structures that your users interact with in your external API. This last point is very important, and is also known as decoupling.
Coupling
Coupling is a data modeling concern that discourages the use of tightly interdependent entities within your application. When entities themselves are strongly interdependent on each other, it's difficult to change or modify one without modifying the others it's tied to. In other words, in a tightly coupled system, small changes end up creating a ripple effect throughout the application and require far more effort to implement and, more importantly, reuse the code elsewhere.
The ER model helps reduce coupling by intentionally isolating each entity from one another, but instead defining relationships between them that can independently evolve, or change over time.
APIs, business logic, and persistence
The ER model and coupling concepts defined above are relevant in so many
aspects of software development. The Issue Tracker application implements
this concept with the core Issue entity and applies it to three different
layers: the API, the business logic, and persistence layers.
The term layer refers to the definition used in Multi-tier architecture, which can be viewed as (yet another) strategy to separate concerns within an application. The layer concerns itself with categorizing different aspects of your application, such as presenting data to your users (the API), controling the application (the business logic), and storing data somewhere so that it can be used again later (the persistence mechanism).
The Issue Tracker defines each of these layers in different Go packages, all
documented with package documentation. The API layer is defined in the
api package, the business logic entities are defined in the entity
package, and the persistence layer entities are defined in the model package.
To drive the relationship between these concepts in, the package documentation for
the entity package is shown below:
For clarity, the database record's primary key is referred to as the EntityID,
which can be seen in the issues table schema. This is a particularly great
example of decoupling in action: the persistence layer defines a primary key
that is not referenced in both the API and business logic layers and makes it
easier to migrate between database technologies if there's ever a need, i.e. if
there are different primary key constraints in specific technologies.
Relational databases
This course focuses on relational databases, and uses SQLite in particular. Note that NoSQL databases certainly have a variety of benefits, but there is always a trade-off (there ain't no such thing as a free lunch). Discussing the trade-offs between these technologies is out-of-scope for this class, but we encourage you to research this topic on your own! This could be a particularly interesting avenue to explore in the Final Project.
Xplenty published a great blog post that describes how to implement decoupled database entities. Please read and review it before continuing to your assignment.