adr-8: decided Discussion
decided 2024-02-25

Architecture Update

A summary of the current architecture of the application

Decision

Hexagonal Architecture

The general philosophy of the project is still to follow a hexagonal architecture pattern. See ADR-02 for a more thorough discussion of what that means.

To quickly summarize: hexagonal architecture is a layered pattern. The core layer encapsulates all of the distinctive logic of the application. The outer layers can be thought of as either drivers or adapters. The core layer defines a number of adapter interfaces, and core services depend on those interfaces. Adapters implement those interfaces, to provide managed interaction with outside services, such as the database, message queues, clients, and so on. Some of these adapters will respond to external input and generally trigger behavior in the rest of the application. It's helpful to think of these as drivers. The Letterbook.Api project is the primary example of a driver at this stage.

All of this relies on dependency injection to function. Some host process is responsible for managing the application lifecycle, and configuring the dependency injection provider. At this stage, that is also Aspnet Core, as configured in Letterbook.Api. In the future, there may be additional configurations with multiple specialized hosts. In order to support easy health checks, those hosts will likely also be aspnet core applications.

Current State

architecture-update-01.svg *not implemented yet

So, generally, core logic services sit in the center of the architecture, and everything else depends on them, or implements an interface that core services depend on. This isolates the core logic from any concerns related to interacting with outside systems or infrastructure. And the adapters are agnostic to the specifics of the core logic. They will generally handle core data models, but mostly to serialize them. Just like with other dependencies, core services should only handle core data models. They should generally not handle serialization or DTOs.

Core Services

In addition, there are a variety of event and message services. These are generally pretty thin, and just exist to consistently schedule messages to an adapter.

Infrastructure

These are not yet implemented, but Letterbook will also depend on an S3-compatible object store, and an email service. Farther down the line, it's also likely we'll optionally incorporate a text search database like ElasticSearch.

Message Queues

In practice, ActivityPub requires some asynchronous message exchanges, often in large volumes. Like most other fediverse servers, Letterbook facilitates this by using message queues. At present, these are all in-memory Observables, provided by Rx.net. In future, this will optionally be provided by a dedicated external message queue, likely RabbitMQ or another AMQP service.

Future Services

There are some obvious categorical feature gaps that will require new services to cover. Which is to say, the software architecture is going to grow a lot over time. Hopefully a short time, at that. For example, we'll need

Discussion

Overlapping Scopes

Sometimes a feature could reasonably be provided by more than one service. For instance, Accounts and Profiles are closely related concepts. Posts and Profiles will both be very closely tied with moderation. It's reasonable to expect that some features at the boundaries of these services might not clearly belong to one service or the other. Resolving that ambiguity is more art than science. It may be tempting to have services depend on each other. That's usually good software engineering practice. But, there's some risk that could introduce redundant queries or API calls, so it's something that should be done with care. If possible, it's likely better to just choose one or the other of the services to perform that behavior. If that's not possible, then you should condsider refactoring the shared behavior into a dedicated class with minimal dependencies, and allow both services to use it from there.

PR Comments

See the original PR for some additional context and tangential discussion