Ramon Lage

Why I chose to start with a simple CRUD API when learning NestJS

15 de enero de 2025

Why I chose to start with a simple CRUD API when learning NestJS

Adopting a new backend framework can be challenging, especially when it comes with strong opinions about structure and architecture.
When I decided to incorporate NestJS into my backend stack, I deliberately chose to start with a simple CRUD API — not as a shortcut, but as a way to evaluate how the framework encourages organization, scalability, and long-term maintainability.

Coming from several years of backend experience, mainly with Python (Django and FastAPI), I was looking for a framework that provided clearer architectural boundaries and stronger typing guarantees. NestJS stood out for its modular design, its integration with TypeScript, and its emphasis on explicit structure.

Why starting with a CRUD still makes sense

CRUD projects are often underestimated, but they cover many of the core responsibilities present in real backend systems:

  • routing and request handling
  • input validation and data contracts
  • persistence and database interaction
  • error handling and response consistency

By keeping the business logic intentionally simple, I was able to focus on how NestJS is meant to be structured and extended, rather than on domain complexity.

Project overview: Recipes API (v1)

This project is a REST API for managing cooking recipes.
The first version focuses on a clean CRUD implementation that serves as a solid foundation for future extensions.

Key characteristics include:

  • versioned endpoints (/api/v1)
  • MongoDB Atlas as the data store
  • Swagger for interactive API documentation
  • deployment on Render for real-world usage

The objective was not to build a feature-complete product, but to establish a clean, extensible backend baseline.

Architecture and structure

The project follows NestJS best practices with a modular architecture and DTO-based validation.

Each feature is organized around:

  • modules to enforce separation of concerns
  • controllers responsible for HTTP interaction
  • services containing business logic
  • DTOs combined with class-validator for input validation

This structure reinforced the value of explicit architectural boundaries, especially when compared to more flexible but less opinionated approaches.

What I learned applying NestJS in practice

Some of the most relevant takeaways from this first iteration were:

  • NestJS encourages thinking about architecture early, even in small projects
  • TypeScript provides confidence when refactoring and evolving the codebase
  • DTO-level validation keeps controllers focused and predictable
  • Consistent structure improves readability and long-term maintainability

Adapting to decorators and dependency injection required an initial mental shift, but once understood, they proved effective for enforcing clear patterns.

What’s next

This project is designed to evolve incrementally. Planned improvements include:

  • user management and JWT-based authentication
  • role-based access control
  • public and private recipe visibility
  • unit and integration testing

Each new feature will build on the existing structure without compromising clarity or stability.

Final thoughts

This project marks an important step in integrating NestJS into my backend toolkit.
Rather than rushing into complex domain logic, I focused on validating the framework’s architectural approach using familiar backend concepts.

Through this blog, I document how different projects represent stages of my technical evolution — applying established backend principles while continuously refining my tools and approaches.