A small function can still do too much
A handler can end up parsing a request, checking authentication, validating data, running business rules, writing to storage and calling an external API in one function. The deployment unit is still small, but the code is not.
Keep HTTP handling near the edge
I prefer to keep request parsing and response formatting separate from the main application logic. The core function can then work with validated values instead of framework-specific request objects.
Give storage and external services a small interface
Database and third-party code are easier to replace or test when the rest of the application depends on the operations it needs instead of provider-specific details.
interface UserRepository {
findById(id: string): Promise<User | null>;
}
interface Mailer {
sendWelcome(email: string): Promise<void>;
}Handle failures where they happen
Authentication failures, unavailable storage and provider timeouts should be translated close to the code that understands them. That keeps unrelated parts of the handler from needing to know every failure shape.