Skip to content

When to compose

The Domain class in Protean acts as a composition root. It manages external dependencies and injects them into objects during application startup.

Your domain should be composed at the start of the application lifecycle. In simple console applications, the main method is a good entry point. In most web applications that spin up their own runtime, we depend on the callbacks or hooks of the framework to compose the object graph, activate the composition root, and inject dependencies into objects.

Accordingly, depending on the software stack you will ultimately use, you will decide when to activate the domain.

Below is an example of composing the domain with Flask as the API framework. You would compose the domain along with the app object, and activate it (push up the context) before processing a request.

import logging.config

from flask import Flask

from protean import Domain
from protean.domain.context import has_domain_context
from protean.fields import Integer, String

domain = Domain(__file__)


@domain.aggregate
class User:
    first_name = String(max_length=50)
    last_name = String(max_length=50)
    age = Integer()


def create_app(config):
    app = Flask(__name__, static_folder=None)

    domain.config.from_object(config)
    logging.config.dictConfig(domain.config["LOGGING_CONFIG"])

    domain.init()

    @app.before_request
    def set_context():
        if not has_domain_context():
            # Push up a Domain Context
            domain.domain_context().push()

    @app.after_request
    def pop_context(response):
        # Pop the Domain Context
        domain.domain_context().pop()

        return response

    return app