MongoDB
Using MongoDB as an output adapter in a hexagonal architecture involves interacting with a NoSQL database to store and retrieve domain entities. MongoDB, being a document-oriented database, is well-suited for applications requiring flexible, schema-less data storage. The adapter translates domain objects into MongoDB documents and vice versa, ensuring the core application remains independent of MongoDB specifics.
Role of MongoDB as an Output Adapter
-
Interfacing with MongoDB:
- The adapter manages the interactions with the MongoDB database, performing CRUD operations to store and retrieve data.
-
Data Translation:
- It converts domain objects into MongoDB documents and translates documents back into domain objects.
-
Decoupling:
- It decouples the core application logic from MongoDB-specific implementation details, promoting flexibility and maintainability.
Benefits of Using MongoDB as an Output Adapter
- Schema Flexibility: MongoDB allows for schema-less data storage, making it easy to evolve the data model over time.
- Scalability: MongoDB supports horizontal scaling through sharding, enabling it to handle large volumes of data.
- Rich Document Model: MongoDB's document model allows for storing complex, nested data structures in a single document.
- Decoupling: The core application logic is decoupled from MongoDB-specific details, ensuring that business logic is independent of the data storage mechanism.
Using MongoDB as an output adapter in a hexagonal architecture provides a flexible and scalable solution for data persistence. By implementing the repository pattern, the core application remains agnostic to the specifics of the MongoDB database, promoting decoupling, flexibility, and maintainability. This approach ensures that the application can leverage the strengths of MongoDB while keeping the business logic clean and independent.
Spec definition
The spec definition can be set via $.spec.adapters.output.mongodb. An example of it could be:
Output adapter MongoDB sample
- The
collection
attribute let you configure the collection name.
Optional metadata
The metadata configuration is optional and if it has not been set defaults values will be used by Torpedo. For the collection name, the entity name will be used to set it up.
MongoDB Repository Implementation
The MongoDB repository has been implemented on top of the Official Go Driver.
And following the Torpedo Repository pattern, two classes will be created, one of it a base repository with CRUD and Query operations and the other one
a main Repository where the custom logic must be placed and with access to the instance of *mongo.Collection
to let developers perform its operations.
The generated code should look like this:
classDiagram
class MongoRepository
class MongoRepositoryBase
interface IRepository
interface IRepositoryBase
IRepositoryBase <|-- IRepository
IRepositoryBase <|.. MongoRepositoryBase
IRepository <|.. MongoRepository
MongoRepositoryBase <|-- MongoRepository
MongoRepositoryBase : mongo.Collection db
MongoRepositoryBase : []byte cryptoKey
MongoRepositoryBase: +Save(entity) error
MongoRepositoryBase: +FetchByID(id) (Entity, error)
MongoRepositoryBase: +Update(entity) error
MongoRepositoryBase: +DeleteByID(id) error
MongoRepositoryBase: +Query(tql.Query) ([]entity,error)
Data Mapper Object (DMO)
DMOs are the selected objects to map entity data into a secondary adapter or storage adapter. These objects are responsible to encrypt or decrypt field values at save/update or fetch operations.
Each time that a repository is created the encryption key must be provided.
AES key
The key argument should be the AES key, either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.
Provider
The MongoDB repository has been tested with MongoDB official driver.
Each entity needs to create their own repository instance and this happens into the entity dependency
provider.
Before to bind
a MongoDB instance as part of your entity provider, a *mongo.Database
provider must be created.
Repository provider
dependency/mongodb.go | MongoDBProvider
Entity provider
Following the example of the section Extending Entity with custom fields
we will need to bind a mongodb
repository to the entity service like the example below:
dependency/sensor.go | SensorProvider
- The mongoDB instance is bound to the default instance provided by MongoDBProvider