# Patterns

## API Composition

{% hint style="warning" %}
Resiliance is super important in Composition Patterns.
{% endhint %}

#### Over Data only

Similar with `CQRS - API Composition Patter`.

<img src="https://323682031-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnlFsbFv50eNWeHeOyBFh%2Fuploads%2FTKMlU1P5XNUrGw8vOWRi%2Ffile.excalidraw.svg?alt=media&#x26;token=b36edbca-307a-4c5e-a2a5-a4c961986180" alt="" class="gitbook-drawing">

{% hint style="success" %}
Compose information from multiple sources.
{% endhint %}

{% hint style="danger" %}
Availability - single point of failure.

Data consistency.

Higher latency.
{% endhint %}

#### Over Business Rules/Services

Where the `API Composition` would be a `Service Composer` that would receive data and run business rules over them, returning after the resulting data.

<img src="https://323682031-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnlFsbFv50eNWeHeOyBFh%2Fuploads%2FdWp5H8PN1YwRNsAO9u0J%2Ffile.excalidraw.svg?alt=media&#x26;token=fe682ee0-4bd5-4813-a007-a8ff6be0ada3" alt="" class="gitbook-drawing">

## Strangler Application

A way to decompose Microservices with two rules:

1. Every new feature will be a microservice.
2. Segregate small peaces of a monolith as a microservice.

At each interation, the monolithic system shrinks until it selft turns into a microservice.

{% hint style="warning" %}
**Difficulties in executing this:**

* Communication with the monolith.
* Team maturity. *(DevOps culture)*
* Data Base. *(Segregating/Migrating) (Tip.: Use APM to help)*
* Each microservice needs an APM from the start.
* Metrics. *(Which metrics you expect for each microservice)*
  {% endhint %}

## ACL (Anti-Corruption Layer)

Just like in `DDD` microservices should use an Anti corruption layer to make services more independent.

In `DDD` an ACL is an `interface`, in microservices an ACL is another microservice in the middle.

<img src="https://323682031-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnlFsbFv50eNWeHeOyBFh%2Fuploads%2FjoA4lCTevs1J9pVSzX4m%2Ffile.excalidraw.svg?alt=media&#x26;token=88040d1d-443c-4a09-8160-fd194fac7aef" alt="" class="gitbook-drawing">

## BFF (Backend for Frontend)

This is a technique used to serve data for specific frontend types, since each type of frontend expects different outputs from APIs.

To do this an [#acl-anti-corruption-layer](#acl-anti-corruption-layer "mention") is used to transform data returned from the APIs, depending on the Frontend that requested.

<img src="https://323682031-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnlFsbFv50eNWeHeOyBFh%2Fuploads%2FsrpNOK1ccplW0xo0PEsP%2Ffile.excalidraw.svg?alt=media&#x26;token=016e5687-1982-4fc1-a7fd-906a3ec70d2f" alt="" class="gitbook-drawing">

{% hint style="success" %}
Since APIs services are big and complex, using BFF they don't have to worry about this optimizations.
{% endhint %}

{% hint style="danger" %}
But this new layer of BFFs will add **latency** to the requests.
{% endhint %}

#### How not to use BFFs

Writing the own API microservice to handle this is a solution if thinking ahead of time.

OR using solutions like `GraphQL`. Since the each Frontend client can choose the excat data that requests.

{% hint style="danger" %}
The downside to this are `GraphQL` own limitations and downsides.
{% endhint %}

## Transactional Outbox

This is a pattern to implement in a Microservice architecture, to highly increase [#resilience](#resilience "mention"), and **avoid that requests don't get lost** when microservices in the chain are **unavailable**. *(Or even communication between Services and Queues)*

{% hint style="info" %}
Mainly used for transactions/requests that are not Sync, so that you don't need real time responses.
{% endhint %}

<img src="https://323682031-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FnlFsbFv50eNWeHeOyBFh%2Fuploads%2FVVsd51VJd0AQMeVD2B87%2Ffile.excalidraw.svg?alt=media&#x26;token=cf5472c6-40d1-4630-bf30-ae474f2fa557" alt="" class="gitbook-drawing">

To garantee that if at any step of the chain, the message won't be lost if a certain Microservice is down (Even with [#retries](#retries "mention") policies), you will have to persist this message in a `Database` or `Queue`.

So in the example of the image above, we could deal with:

### With `Database`

`MS 1` will have a Database specific for persisting these messages.

When `MS 1` action starts the Message is persisted, and when `MS 1` action ends it deletes from the Database.

Then if communication to `MS 2` fails the message is persisted and `MS 1` can still retry.

{% hint style="warning" %}
The ideia would be a Database for each MS, but I guess the Database could be global and shared between all of them.

Just think about resilience and the repercussion of this.
{% endhint %}

{% hint style="info" %}
*Examples of Database to use:*

`RDBMS`

`KV -> DynamoDB`

`Cache -> Redis`

**It is important to not mix this Database with the MS data Database.**
{% endhint %}

### With global `Queue`

Just like in the solution above, messages are produced when arrived in each Microservice, and a consumer runs on each of them, consuming the message as soon they finish.

## Secret Manager

A mechanism to store Credentials inside a Microservice environment, so that they are not stored inside `Environment Variables` or stored inside the Microservices.

{% hint style="success" %}
This solution makes much easier to automatically rotate these passwords.
{% endhint %}

## Logs

{% hint style="danger" %}
All logs from Microservices should be **standardized**.
{% endhint %}

{% hint style="danger" %}
Use `OTEL` (Open Telemetry) to mask and decouple which tools you use for Logs, Metrics and Telemetry *(like New Relic, Datadog, Elastic, etc)* from your architecture.
{% endhint %}

#### Good practice examples

{% hint style="info" %}
**Unify log lines to a single line:**

Depending on the language or tools, it generates stack traces of logs or similars.

But a standerdized log should be in 1 line only.
{% endhint %}

More information, best practices and examples can be seen in .
