Files
calendar/agents/rules/api-thin-controllers.md
T
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
d4ea931bf8 feat(agents): add modular engineering rules from 2026 standards (#26847)
* feat(agents): add modular engineering rules from 2026 standards

Add a rules directory with individual rule files derived from the
Cal.com Engineering in 2026 and Beyond blog post. Rules are organized
by section (architecture, quality, data, api, performance, testing,
patterns, culture) following the Vercel agent-skills structure.

Includes:
- _sections.md defining rule categories and impact levels
- _template.md for creating new rules
- 14 individual rule files covering key engineering standards
- README documenting the rules structure and usage

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat(agents): consolidate DI and Repository+DTO docs into rules

- Move di-pattern.md content to rules/patterns-di-pattern.md
- Extract Repository + DTO section from knowledge-base.md into:
  - rules/data-repository-methods.md (method naming conventions)
  - rules/data-dto-boundaries.md (DTO location and naming)
- Update knowledge-base.md to reference the new rule files
- Delete old di-pattern.md file

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore(agents): remove stub reference sections from knowledge-base.md

The rules directory is self-contained with its own README, so these
redirect sections are unnecessary clutter.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor(agents): combine DI pattern rules into single file

Merged patterns-di-pattern.md into patterns-dependency-injection.md
to eliminate overlap and create one comprehensive DI guide.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-16 10:57:28 +01:00

2.4 KiB

title, impact, impactDescription, tags
title impact impactDescription tags
Keep Controllers Thin - HTTP Concerns Only HIGH Enables technology-agnostic business logic api, controllers, http, separation-of-concerns

Keep Controllers Thin - HTTP Concerns Only

Impact: HIGH

Controllers are thin layers that handle only HTTP concerns. They take requests, process them, and map data to DTOs that are passed to core application logic. No application or core logic should be seen in API routes or tRPC handlers.

Controller responsibilities (and ONLY these):

  • Receive and validate incoming requests
  • Extract data from request parameters, body, headers
  • Transform request data into DTOs
  • Call appropriate application services with those DTOs
  • Transform application service responses into response DTOs
  • Return HTTP responses with proper status codes

Controllers should NOT:

  • Contain business logic or domain rules
  • Directly access databases or external services
  • Perform complex data transformations or calculations
  • Make decisions about what the application should do
  • Know about implementation details of the domain

Incorrect (business logic in controller):

export async function POST(request: Request) {
  const body = await request.json();
  
  // Business logic in controller - BAD
  const user = await prisma.user.findFirst({ where: { id: body.userId } });
  if (!user.canBook) {
    return Response.json({ error: "Cannot book" }, { status: 403 });
  }
  
  const booking = await prisma.booking.create({
    data: {
      title: body.title,
      startTime: new Date(body.startTime),
      // Complex logic here...
    }
  });
  
  return Response.json(booking);
}

Correct (thin controller):

export async function POST(request: Request) {
  const body = await request.json();
  
  // Validate input
  const input = CreateBookingSchema.parse(body);
  
  // Delegate to service
  const result = await bookingService.createBooking(input);
  
  // Transform and return
  return Response.json(BookingResponseSchema.parse(result));
}

The principle: We must detach HTTP technology from our application. The way we transfer data between client and server (whether REST, tRPC, etc.) should not influence how our core application works. HTTP is a delivery mechanism, not an architectural driver.

Reference: Cal.com Engineering Blog