Find out how much you could save by firm size view a cost analysis.

See the savings

Find out how much you could save by firm size view a cost analysis.

See the savings

Find out how much you could save by firm size view a cost analysis.

See the savings

Feb 17, 2025

Feb 17, 2025

Feb 17, 2025

Engineering: Building Maintainable FastAPI Services: A Feature-Driven Approach

Engineering: Building Maintainable FastAPI Services: A Feature-Driven Approach

Engineering: Building Maintainable FastAPI Services: A Feature-Driven Approach

Stephanie Goldman

Stephanie Goldman

Stephanie Goldman

Founder at Gridlines

Founder at Gridlines

Table of Contents

Our Journey from Flask to FastAPI

Before diving into our current architecture, it's worth sharing our journey. Like many Python web applications, we started with Flask. Flask served us well in the early days - it's simple, well-documented, and has a great ecosystem. However, as our application grew, we faced several challenges:

  1. Async Limitations: Flask's synchronous nature became a bottleneck, especially when dealing with multiple database queries and external API calls.

  2. Schema Validation: We found ourselves writing lots of manual validation code for request/response data.

  3. API Documentation: Maintaining up-to-date API documentation required significant effort.

  4. Type Safety: As our codebase grew, we wanted better type hints and validation.

FastAPI addressed all these pain points:

  • Built-in async support with modern Python async/await syntax

  • Automatic request/response validation with Pydantic

  • OpenAPI documentation out of the box

  • First-class support for Python type hints

The migration from Flask to FastAPI not only improved our performance but also gave us an opportunity to rethink our architecture. That's when we adopted the feature-first approach.


Traditional vs. Feature-First Architecture

When building FastAPI applications at scale, one of the most crucial decisions is how to organize your code. While many tutorials show a layer-first approach, we've found that a feature-first architecture leads to better maintainability, clearer boundaries, and improved developer experience.

Let's look at how these approaches differ:

Traditional Layer-First Structure


Feature-First Structure


Why Feature-First Makes Sense

1. Domain Cohesion

In a feature-first architecture, all code related to a specific feature lives together. This means when you're working on the user management feature, everything you need is in the users directory. Let's look at a complete feature implementation:

# users/schema.py
from pydantic import BaseModel, EmailStr

class UserCreate(BaseModel):
    username: str
    email: EmailStr
    password: str

class UserResponse(BaseModel):
    id: int
    username: str
    email: EmailStr
    is_active: bool

# users/service.py
from .schema import UserCreate, UserResponse
from fastapi import HTTPException
from typing import List

class UserService:
    def __init__(self, db_session):
        self.db = db_session

    async def create_user(self, user: UserCreate) -> UserResponse:
        # Business logic here
        pass

    async def get_users(self) -> List[UserResponse]:
        # Business logic here
        pass

# users/router.py
from fastapi import APIRouter
from .service import UserService
from .schema import UserCreate, UserResponse
from typing import List

router = APIRouter(prefix="/users", tags=["users"])

@router.post("/", response_model=UserResponse)
async def create_user(user: UserCreate):
    service = UserService(db_session=None)  # You'll need to pass your actual db session here
    return await service.create_user(user)

@router.get("/", response_model=List[UserResponse]

2. Clear Boundaries

Each feature folder is a self-contained module with clear responsibilities. This makes it easier to:

  • Understand the scope of each feature

  • Maintain separation of concerns

  • Prevent unwanted dependencies between features

  • Test features in isolation

3. Scalability Benefits

As your application grows, feature-first architecture provides several advantages:

  1. Easier Microservices Migration: Each feature folder can become its own microservice with minimal refactoring.

  2. Independent Development: Teams can work on different features without stepping on each other's toes.

  3. Simplified Deployments: Features can be deployed independently if needed.

4. Developer Experience

The feature-first approach significantly improves developer experience:

  1. Reduced Context Switching: No need to jump between multiple folders when working on a feature

  2. Clear Ownership: Teams can own entire features rather than layers

  3. Faster Onboarding: New developers can understand features in isolation

  4. Better Code Reviews: Changes for a feature are contained in one place

Handling Shared Code

One common question is how to handle shared code in this architecture. Here's our approach:


The core directory contains shared utilities, configurations, and dependencies that multiple features might need.

Best Practices

  1. Keep Features Independent

    • Minimize cross-feature dependencies

    • Use events or well-defined interfaces for feature communication

    • Think twice before sharing code between features

  2. Consistent Internal Structure

    • Each feature should follow the same structure (router, service, schema)

    • Use consistent naming conventions

    • Maintain similar patterns across features

  3. Clear Feature Boundaries

    • Each feature should have a clear, single responsibility

    • Avoid creating "utility" features

    • If multiple features need similar functionality, consider if it belongs in core

  4. Documentation

    • Each feature should have its own README.md

    • Document feature-specific configuration and dependencies

    • Include feature-level testing instructions

Testing in Feature-First Architecture

The feature-first approach makes testing more straightforward:


Each feature has its own tests, making it easy to:

  • Run tests for specific features

  • Maintain test data and fixtures close to the tests

  • Achieve high test coverage for critical features

How do other teams do it?

Many major tech companies use feature-first (also called vertical slice) architecture in their applications, though they might call it by different names. Here are some notable examples:

  1. Netflix

  • Uses a similar feature-based organization in their microservices

  • Each service is organized around business capabilities/features

  • This inspired their famous "Netflix Stack" architecture

  1. Spotify

  • Known for their "Squad" model where teams own entire features

  • Their code organization mirrors their team structure (Conway's Law)

  • Features are organized as independent "tribes"

  1. Microsoft

  • Uses feature-based organization in many of their .NET applications

  • Has been promoting "vertical slice architecture" through their documentation

  • Jimmy Bogard (Microsoft MVP) heavily advocates for this approach

  1. Facebook

  • Their React codebase is organized by features

  • Mobile app structure follows feature-first patterns

  • Each feature team owns their entire stack

  1. Amazon

  • "Two Pizza Teams" model naturally led to feature-based code organization

  • Each service is typically organized around specific business capabilities

  • Teams own features end-to-end

However, it's important to note that:

  • Most companies don't strictly follow just one pattern

  • They often adapt and blend different architectural approaches

  • The implementation varies based on team size and business needs

  • They might use different architectures for different parts of their systems

Conclusion

Feature-first architecture is a powerful way to organize FastAPI applications. It provides clear boundaries, improves developer experience, and makes your codebase more maintainable as it grows. While it might take some time to adjust if you're used to layer-first architecture, the benefits become clear as your application scales.

Remember, the goal of any architecture is to make development easier and more maintainable. Feature-first architecture achieves this by keeping related code together and establishing clear boundaries between different parts of your application.

Consider adopting this approach in your next FastAPI project, especially if you anticipate it growing beyond a few simple endpoints. The initial investment in organization will pay dividends as your application evolves.

About the Author

Stephanie Goldman

Stephanie Goldman

Founder at Gridlines

I enjoy the intersection between finance and software engineering. I previously worked at Barclays as an Investment Banking Analyst and at GI Partners as a Private Equity Associate.

I enjoy the intersection between finance and software engineering. I previously worked at Barclays as an Investment Banking Analyst and at GI Partners as a Private Equity Associate.

I enjoy the intersection between finance and software engineering. I previously worked at Barclays as an Investment Banking Analyst and at GI Partners as a Private Equity Associate.

Boosting analyst efficiency by automating document analysis and slide creation for investment banks

Product

AI-Powered slide creation

Data validation

Use Cases

Pitch book creation

CIM development

Client presentations

Ad hoc materials

Due diligence analysis

Market updates

Industries

Investment Banking

Private Equity

Consulting

Company

About Us

Careers

Gridlines, Inc. © 2025. All rights reserved

Boosting analyst efficiency by automating document analysis and slide creation for investment banks

Product

AI-Powered slide creation

Data validation

Use Cases

Pitch book creation

CIM development

Client presentations

Ad hoc materials

Due diligence analysis

Market updates

Industries

Investment Banking

Private Equity

Consulting

Company

About Us

Careers

Gridlines, Inc. © 2025. All rights reserved

Boosting analyst efficiency by automating document analysis and slide creation for investment banks

Product

AI-Powered slide creation

Data validation

Use Cases

Pitch book creation

CIM development

Client presentations

Ad hoc materials

Due diligence analysis

Market updates

Industries

Investment Banking

Private Equity

Consulting

Company

About Us

Careers

Gridlines, Inc. © 2025. All rights reserved