Setup¶
Introduction¶
Before starting to think in multiple microservices, distributed environments and so on, it’s easier and better to start by knowing what components are needed to build a microservice individually. For the sake of simplicity, each microservice can be seen as one small monolithic system that provides as limited or specialized functionality. Then, each microservice will probably need to interact with a storage system, contain some kind of business logic and expose that functionality over an external API, to be used by external clients and another microservices.
Dependencies¶
To be able to provide all that environment functionalities, minos
relies on external dedicated libraries. For example,
to read or store data in postgres database aiopg
is used, to publish or subscribe to kafka topics aiokafka
is used
and to expose a REST interface aiohttp
is used. In any case, the minos
philosophy is that the surrounding
technologies must not be frozen to these and each of project must have its own ones so the list of supported databases
and brokers will be increased in future minos
releases.
Another important thing to know is that minos
relies on latest Python
functionalities so the minimal required
version is 3.9
or greater. One of the reasons are the use of async code together with type hinted code.
Then, for this quickstart the following dependencies are needed:
Python >= 3.9
PostgreSQL >= 9.3
Kafka >= 2.8
In order to ease the quickstart process, here is a simple docker-compose.yml
that provides the environment
dependencies:
# docker-compose.yml
version: "3.9"
services:
postgres:
image: postgres:latest
ports:
- "5432:5432"
environment:
POSTGRES_USER: minos
POSTGRES_PASSWORD: min0s
POSTGRES_DB: exam_db
zookeeper:
image: wurstmeister/zookeeper:latest
ports:
- "2181:2181"
kafka:
image: wurstmeister/kafka:latest
ports:
- "9092:9092"
depends_on:
- zookeeper
environment:
KAFKA_ADVERTISED_HOST_NAME: localhost
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_DELETE_TOPIC_ENABLE: "true"
Modularity¶
Another important detail about how the minos
framework is how it is packaged. Instead of providing all the framework
as a single and big component, it relies
on Python
namespaces to provide a modular but
organized way to install only the exact part of functionality that will be used. The main packages are the following
ones:
minos-microservice-common: Contains the
minos.common
module.minos-microservice-networks: Contains the
minos.networks
module.minos-microservice-saga: Contains the
minos.saga
module.minos-microservice-cqrs: Contains the
minos.cqrs
module.
Package Managers¶
Before starting a Python
project, a package manager is needed to install and manage external dependencies. As it’s
expected, minos
is compatible with any of them, but the recommended one is Poetry
as it provides simple but powerful
functionalities.
Poetry¶
To install poetry, it’s recommended to follow its own guide, that can be found here.
After installing poetry
, everything is ready to build the first microservice!
The first step is to create the project (the project name can be whatever you want, but a minos
microservice
convention is to name it as src
):
poetry new exam-microservice-example --name src
The project structure will be similar to:
exam-microservice-example
├── README.rst
├── pyproject.toml
├── src
│ └── __init__.py
└── tests
├── __init__.py
└── test_src.py
2 directories, 5 files
To install the minos
dependencies, simply exec the following command on the project’s root directory:
poetry add \
minos-microservice-common \
minos-microservice-networks \
minos-microservice-saga \
minos-microservice-cqrs
PipEnv¶
[TODO: Include pipenv guide.]
Pip¶
[TODO: Include pip guide.]
After that, every minos
dependencies are ready to use. Let’s move to the configuration step!
Configuration¶
The configuration step is the last part of the microservice’s setup, which is the process of defining the microservice’s name, the classes to be responsible for specific framework’s tasks and the location of credentials to interact with external resources like databases and brokers.
As many parts of the configuration requires digging deeper into each of the components of the framework, here is provided a superficial description of the main ones.
service.name
: The name of the microservice.service.aggregate
: The qualifiedPython
path to the root aggregate.service.injections
: A mapping of instances to be injected around the framework to provide framework’s functionality.service.services
: A set of background services whose main purpose that provide some framework’s functionality.rest
: Configuration of the rest’s interface.broker
: Configuration of the broker’s interface.repository
: Configuration of the repository database.snapshot
: Configuration of the snapshot database.events
: Configuration of the events service.queries
: Configuration of the queries service.commands
: Configuration of the commands service.saga
: Configuration of the saga manager.discovery
: Configuration of the discovery service.
Here is a template for a config.yml
file, which will be used by the exam
microservice.
# config.yml
service:
name: exam
aggregate: src.aggregates.Exam
injections:
postgresql_pool: minos.common.PostgreSqlPool
command_broker: minos.networks.CommandBroker
command_reply_broker: minos.networks.CommandReplyBroker
event_broker: minos.networks.EventBroker
consumer: minos.networks.Consumer
dynamic_handler_pool: minos.networks.DynamicHandlerPool
repository: minos.common.PostgreSqlRepository
saga_manager: minos.saga.SagaManager
snapshot: minos.common.PostgreSqlSnapshot
# discovery: minos.networks.DiscoveryConnector
query_repository: src.queries.ExamQueryRepository
services:
- minos.networks.ConsumerService
- minos.networks.CommandHandlerService
- minos.networks.CommandReplyHandlerService
- minos.networks.EventHandlerService
- minos.networks.RestService
- minos.networks.SnapshotService
- minos.networks.ProducerService
rest:
host: 0.0.0.0
port: 8082
broker:
host: localhost
port: 9092
queue:
database: exam_db
user: minos
password: min0s
host: localhost
port: 5432
records: 1000
retry: 2
repository:
database: exam_db
user: minos
password: min0s
host: localhost
port: 5432
snapshot:
database: exam_db
user: minos
password: min0s
host: localhost
port: 5432
queries:
service: src.queries.ExamQueryService
commands:
service: src.commands.ExamCommandService
saga:
storage:
path: ./exam.lmdb
# TODO: include discovery service into the `docker-compose.yml`
# discovery:
# client: minos.networks.MinosDiscoveryClient
# host: localhost
# port: 5567
API Gateway and Discovery¶
[TODO: Describe integration with discovery.]