Object Storage: S3 & GCS
Relevant source files
The following files were used as context for generating this wiki page:
Object storage in the Forze framework provides a standardized interface for handling blob data, such as files and attachments, using S3-compatible backends or Google Cloud Storage (GCS). By utilizing Hexagonal Architecture principles, the framework decouples the application logic from specific storage providers through logical specifications and abstract ports.
The system is split using a Command Query Responsibility Segregation (CQRS) pattern. Operations related to data modification (upload, delete) are handled by the StorageCommandPort, while retrieval operations (download, list) are handled by the StorageQueryPort. This allows for flexible wiring and testing using mock adapters without requiring active cloud infrastructure.
Sources: skills/forze-storage-s3/SKILL.md, skills/forze-storage-gcs/SKILL.md, skills/forze-framework-usage/SKILL.md
Architecture and Ports
The storage system operates through a clear separation of logical definitions (Specs) and physical implementation (Adapters).
Storage CQRS Split
Forze enforces a strict split between read and write operations for object storage.
- StorageCommandPort: Responsible for
uploadanddeleteoperations. - StorageQueryPort: Responsible for
downloadandlistoperations.
This separation allows developers to resolve only the necessary capabilities within a handler, improving security and clarity.
The diagram shows how a handler interacts with the ExecutionContext to resolve specific storage ports based on a StorageSpec.
Sources: skills/forze-storage-s3/SKILL.md, skills/forze-framework-usage/SKILL.md
Logical Specifications (Specs)
The StorageSpec is a logical identifier used within the domain and application layers. It does not contain infrastructure-specific details like bucket names or cloud credentials. Instead, it defines the logical name and attributes of the storage resource.
| Field | Type | Description |
|---|---|---|
name | str | StrEnum | The logical route ID used to map the spec to infrastructure config. |
Sources: src/forze/application/contracts/storage/specs.py:5-9, skills/forze-specs-infrastructure/SKILL.md
Mapping Specs to Infrastructure
Infrastructure wiring occurs in dependency modules (S3DepsModule or GCSDepsModule). These modules map the logical name from the StorageSpec to physical configuration such as bucket names and tenant awareness.
# Spec definition in Domain/Application layer
attachments_spec = StorageSpec(name="project-attachments")
# Infrastructure wiring in Composition layer
s3_module = S3DepsModule(
client=s3_client,
storages={
"project-attachments": {
"bucket": "prod-files-bucket",
"tenant_aware": True,
}
},
)
Sources: skills/forze-storage-s3/SKILL.md, skills/forze-specs-infrastructure/SKILL.md
Multi-Tenancy
Object storage supports tenant isolation through the tenant_aware configuration. When enabled, the storage adapter automatically derives tenant information from the ExecutionContext.
- Derivation: The adapter extracts
TenantIdentitybound at the interface boundary (e.g., HTTP or queue worker). - Routing: The adapter uses this identity to route objects to tenant-specific paths or buckets.
- Constraint: Tenant IDs should not be passed through domain DTOs for storage routing; they must be managed via the context.
Sources: skills/forze-storage-s3/SKILL.md, skills/forze-storage-gcs/SKILL.md
Implementation: S3 and GCS
Amazon S3 and S3-Compatible Storage
The S3 integration uses aioboto3 and aiobotocore for asynchronous operations. It supports collision-resistant object key generation and automatic content type detection.
- Lifecycle: Managed via
s3_lifecycle_step, which configures endpoints, credentials, and connection pools. - Compatibility: Works with AWS S3 and compatible services like MinIO.
Sources: skills/forze-storage-s3/SKILL.md, pyproject.toml:68-75
Google Cloud Storage (GCS)
The GCS integration utilizes the gcloud-aio-storage library.
- Lifecycle: Configured via
gcs_lifecycle_step. - Authentication: Supports Application Default Credentials (ADC), workload identity, or explicit service account JSON files.
- Emulator: Supports
fake-gcs-serverfor local development by setting theSTORAGE_EMULATOR_HOSTenvironment variable.
Sources: skills/forze-storage-gcs/SKILL.md, pyproject.toml:84-85
Usage Pattern
A typical handler uses the ExecutionContext to resolve the required storage port and perform operations using StoredObject and UploadedObject data structures.
The sequence diagram illustrates the flow of an upload operation from a handler through the storage port to the S3 adapter.
Sources: skills/forze-storage-s3/SKILL.md, skills/forze-framework-usage/SKILL.md
Testing with Mocks
Forze provides a MockStorageAdapter within forze_mock. This allows unit tests to execute storage logic without real cloud dependencies.
- Mock Registration:
MockDepsModuleautomatically registersStorageQueryDepKeyandStorageCommandDepKey. - Behavior: It simulates uploads and downloads in-memory, ensuring that application handlers can be tested in isolation.
Sources: skills/forze-storage-s3/SKILL.md, skills/forze-storage-gcs/SKILL.md
Conclusion
The Object Storage system in Forze provides a provider-agnostic way to manage blobs through S3 and GCS integrations. By separating logical StorageSpec definitions from physical S3DepsModule configurations, the framework ensures that domain logic remains pure while allowing infrastructure to scale and vary across environments. The CQRS-based port design further enhances testability and security by restricting handlers to specific read or write capabilities.