Skip to content

Instantly share code, notes, and snippets.

@jfacoustic
Created May 13, 2026 21:58
Show Gist options
  • Select an option

  • Save jfacoustic/0d7e53d98c31abd20946a16925f97e9d to your computer and use it in GitHub Desktop.

Select an option

Save jfacoustic/0d7e53d98c31abd20946a16925f97e9d to your computer and use it in GitHub Desktop.
Clean Architecture BFF Guidelines

Clean Architecture & the Backend-for-Frontend (BFF)

Overview

This document outlines our architectural approach for mobile development, combining Clean Architecture principles with a Backend-for-Frontend (BFF) pattern and contract-driven API development.


Clean Architecture

Clean Architecture organizes code into concentric layers with a strict dependency rule: inner layers know nothing about outer layers.

┌─────────────────────────────────────────────┐
│              External Services               │  ← Frameworks, DBs, APIs
├─────────────────────────────────────────────┤
│           Interface Adapters                 │  ← Controllers, Gateways
├─────────────────────────────────────────────┤
│             Use Cases                        │  ← Application logic
├─────────────────────────────────────────────┤
│              Entities                        │  ← Core business rules
└─────────────────────────────────────────────┘

Key principles:

  • Independence from frameworks — Business logic doesn't depend on any specific technology.
  • Testability — Use cases can be tested without UI, database, or external services.
  • Independence from external agencies — Internal services, auth providers, and databases are implementation details that can be swapped.

How Clean Architecture Applies to Our BFF

The BFF sits between the mobile app and internal services, acting as an orchestration and translation layer purpose-built for the mobile client's needs.

System Architecture

Mobile App
 └──▶ PingFed Auth
 └──▶ BFF (acad-mobile-bff)
       └──▶ Internal Services (Data Manager, future services)

BFF Layer Mapping

Clean Architecture Layer BFF Responsibility
Entities Domain models representing core business concepts
Use Cases Orchestration logic — aggregating, transforming, and composing data from internal services
Interface Adapters API controllers (serving the contract), service clients (calling downstream services)
External Internal services (Data Manager), auth (PingFed), infrastructure concerns

The BFF does not own business logic. It orchestrates calls to internal services and shapes responses specifically for the mobile app's consumption.


Contract-Driven API Development

The API specification (OpenAPI or GraphQL schema) is the language-agnostic source of truth for all communication between the mobile app and the BFF.

The Contract as the Boundary

┌────────────────┐       ┌──────────────────┐       ┌────────────────────┐
│   Mobile App   │◀─────▶│  API Spec (Contract)  │◀─────▶│       BFF          │
│                │       │  OpenAPI / GraphQL     │       │                    │
│  Generated     │       │                        │       │  Generated         │
│  Client + Models│      │  Hosted in BFF project │       │  Interfaces        │
└────────────────┘       └──────────────────┘       └────────────────────┘
  • The specification lives in and is hosted by the BFF project.
  • Front end generates API clients and models from the specification.
  • Back end generates server interfaces/stubs from the specification.
  • Neither side hand-writes the contract boundary — it is always generated from the shared spec.

This ensures both sides are always in sync and eliminates an entire class of integration bugs.


Development Workflow

Coordination Process

  1. Front end and back end developers collaborate on defining the API specification for new features.
  2. The agreed-upon spec is committed to the BFF project.
  3. Front end developers generate clients and models from the hosted spec.
  4. Back end developers implement the orchestration logic behind the generated interfaces.

Front End Developer Experience

  • Interactive testing — Swagger UI or GraphiQL endpoints are available for exploring and testing API calls directly.
  • Local BFF — Front end developers can run the BFF locally to test against real or mocked responses.
  • Mock data for new endpoints — When a new endpoint is defined in the spec but not yet implemented, the BFF serves generated mock data. Once back end developers implement the orchestration, the mock is replaced transparently.

This means front end development is never blocked by back end implementation timelines.

Development Timeline (Parallel Workstreams)

Spec Defined ──────────────────────────────────────────▶

Front End:   [Generate Client] ──▶ [Build UI w/ Mocks] ──▶ [Integration Test]

Back End:    [Generate Interfaces] ──▶ [Implement Orchestration] ──▶ [Mock Replaced]

Practical Example: User Streaks

To illustrate how this works end-to-end, consider adding a "User Streaks" feature that shows a student's consecutive daily activity.

1. Define the Contract

Front end and back end developers agree on the streak endpoint shape in the API specification — request parameters, response structure, and error cases. This is committed to the BFF project.

2. Front End Begins Immediately

  • Generates an updated API client from the new spec.
  • The BFF serves mock streak data (e.g., a sample 7-day streak with placeholder dates).
  • The mobile app builds the streak UI, progress indicators, and edge case handling against this mock.

3. Back End Implements Orchestration

  • The BFF's generated interface defines the method signature for the streak endpoint.
  • The back end developer implements the use case: calling Data Manager to retrieve activity records, computing the streak, and returning the shaped response.
  • Once implemented, the mock is replaced — the front end requires no changes.

4. Integration

Both sides already conform to the same contract. Integration is a verification step, not a development phase.


Guidelines Summary

Guideline Rationale
The API spec is the source of truth Eliminates drift between client and server
Generate, don't hand-write, boundary code Reduces human error at integration points
Mock new endpoints by default Unblocks parallel development
BFF orchestrates, doesn't own business logic Keeps the BFF thin and focused on client needs
Front end devs can run the BFF locally Shortens feedback loops
Interactive API exploration is always available Reduces onboarding friction and speeds debugging

Key Takeaways

  • Clean Architecture keeps our BFF maintainable and testable by enforcing clear boundaries between orchestration logic and external dependencies.
  • Contract-driven development ensures the mobile app and BFF evolve together without integration surprises.
  • Mock-first endpoint development enables true parallel workstreams — no team waits on another.
  • The BFF is a thin orchestration layer, not a place for business logic. It exists to serve the mobile app's specific needs by composing responses from internal services.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment