К основному содержанию
правило

nestjs · sanjeed5 — правило для Cursor: структура и типы в NestJS

Правило для Cursor задаёт структуру NestJS-проекта: модули по фичам, явные типы, DTO с валидацией и глобальные фильтры ошибок.

Установить в Cursor · Вручную: положить файлы Все способы и платформы ↓
.cursor/rules/nestjs.mdc
Открыть на GitHub

Что делает nestjs

Правило описывает, как раскладывать код NestJS: каждый бизнес-домен получает свой модуль, а не общую папку controllers или services. Внутри модуля — контроллеры, сервисы, репозитории и DTO по отдельным папкам. Файлы и папки именуются в kebab-case, классы — в PascalCase, интерфейсы — с префиксом I, константы — в UPPER_SNAKE_CASE.

Отдельный блок про типы: правило требует явных типов у переменных, параметров и возвращаемых значений, а any запрещает. В tsconfig.json нужен строгий режим TypeScript. Для входящих запросов — DTO с декораторами class-validator (@IsString, @IsEmail, @MinLength), а не сырое тело запроса. Зависимости внедряются через конструктор, new для сервисов не используется.

Ошибки собираются в глобальный фильтр: класс с @Catch(HttpException) форматирует ответ, а в main.ts он подключается через app.useGlobalFilters. Вместо try/catch в каждом методе. Доступ к маршрутам закрывается гардом с Reflector и проверкой ролей. Учтите: правило рассчитано на NestJS с TypeScript, и без class-validator примеры DTO не заработают.

Какие задачи решает

  • разложить код по модулям вместо общих папок controllers и services
  • убрать any и расставить явные типы в сервисах
  • проверять тело запроса через DTO с class-validator
  • собрать единый формат ответа об ошибке вместо try/catch в каждом методе
  • закрыть маршруты проверкой ролей через гард

Примеры запросов агенту

  • Разложи модуль users по фичам: контроллер, сервис, репозиторий и DTO в отдельных папках
  • Добавь DTO для создания пользователя с валидацией class-validator вместо any
  • Подключи глобальный HttpExceptionFilter в main.ts и убери try/catch из контроллеров

Как установить nestjs

Вручную: положить файлы

.cursor/rules/nestjs.mdc

Во frontmatter: description, globs, alwaysApply

По шагам, с командами для каждой платформы: Cursor rules: файлы .mdc, четыре режима и замена .cursorrules

Из того же набора69

phoenix Правило для Cursor задаёт, как писать Phoenix-приложения на Elixir: контексты, форматирование, тесты. Пригодится, если агент уже правит ваш код. ★ 3 579звёзд репо pandas Правило для Cursor задаёт стиль работы с pandas: векторизация вместо циклов, явные .loc и .iloc, экономные типы данных. Пригодится, если агент часто пишет медленный код. ★ 3 579звёзд репо notion-api Правило для Cursor задаёт, как писать код интеграций с Notion API: модули, токены в переменных окружения, официальные SDK и пагинация. ★ 3 579звёзд репо nginx Правило для Cursor задаёт, как писать конфиги NGINX: модульные include-файлы, современный TLS, кэш и лимиты. Пригодится, если агент правит nginx.conf в вашем проекте. ★ 3 579звёзд репо mongodb Правило для Cursor с набором практик по моделированию данных, запросам и индексам в MongoDB. Помогает агенту не плодить лишние $lookup и медленные запросы. ★ 3 579звёзд репо mobx Правило для Cursor задаёт структуру MobX-приложения на React: единый RootStore, явные observables и observer только на листовых компонентах. ★ 3 579звёзд репо microsoft-teams Правило для Cursor с набором практик разработки приложений Microsoft Teams: структура проекта, Fluent UI, Adaptive Cards и Microsoft Graph. ★ 3 579звёзд репо material-ui Правило задаёт Cursor единый стиль работы с Material-UI: структура папок, тема, стили и компоненты. Пригодится, если проект на React с MUI растёт и хочется одинаковых решений. ★ 3 579звёзд репо

Другие версии nestjs

Похожие

nestjs-best-practices giuseppe-trisciuoglio Скилл задаёт агенту правила NestJS: модули, области видимости провайдеров, фильтры исключений, DTO-валидация и Drizzle ORM. CX Codex +1 3 800установок nestjs-expert https://github.com/Jeffallan Скилл помогает проектировать и писать NestJS бэкенд-приложения на TypeScript: модули, сервисы, контроллеры, валидацию, аутентификацию и тесты. Нужен, если строишь REST API или GraphQL с enterprise-паттернами. CX Codex +1 5 900установок nestjs-patterns affaan-m Скилл задаёт архитектурные правила для бэкендов на NestJS и TypeScript: от структуры каталогов до валидации DTO и тестов. CX Codex +1 5 000установок nestjs-code-review giuseppe-trisciuoglio Скилл для ревью NestJS-приложений: проверяет контроллеры, сервисы, модули, DI, гарды и работу с базой. Пригодится перед мержем пул-реквеста. CX Codex +1 3 800установок nestjs-modular-monolith Felipe Rodrigues - github.com/felipfr Ведёт от анализа домена до кода: границы модулей, DDD, Clean Architecture и CQRS в одном бэкенде на NestJS. CX Codex +1 329установок openapi-to-application-nodejs-nestjs официальный Awesome Copilot Community Собирает приложение на NestJS по спецификации OpenAPI: скаффолдинг проекта, контроллеры, сервисы. Пригодится, когда контракт API уже есть, а кода ещё нет. ★ 40 418звёзд репо

Рядом в теме «Бэкенд и API»

Всё по теме «Бэкенд и API» →

Вопросы о nestjs

Как установить правило nestjs в Cursor?

Создайте файл .cursor/rules/nestjs.mdc в корне проекта и вставьте в него содержимое правила.

Что делает правило nestjs?

Задаёт структуру NestJS-приложения: модули по фичам, соглашения об именах, явные типы, DTO с валидацией, глобальные фильтры ошибок и гарды для ролей.

Что нужно для работы примеров из правила?

Проект на NestJS с TypeScript и строгим режимом в tsconfig.json. Для DTO понадобится class-validator.

Исходный текст

nestjs.mdc · CC0-1.0
---
description: This guide provides opinionated, actionable best practices for building robust, scalable, and maintainable NestJS applications using TypeScript, emphasizing modern patterns and common pitfalls.
globs: **/*.{ts,tsx}
---
# NestJS Best Practices

NestJS is a powerful framework for building scalable Node.js applications. Adhering to these guidelines ensures your projects are maintainable, performant, and secure.

## 1. Code Organization and Structure

Adopt a feature-based, semi-hexagonal architecture. Each business domain gets its own module.

### ✅ GOOD: Feature-based Modules
Organize code by feature, not by type.

```typescript
// src/modules/users/users.module.ts
@Module({
  controllers: [UsersController],
  providers: [UsersService, UsersRepository],
  exports: [UsersService],
})
export class UsersModule {}
// src/modules/users/controllers/users.controller.ts
// src/modules/users/services/users.service.ts
// src/modules/users/repositories/users.repository.ts
// src/modules/users/dtos/create-user.dto.ts
```

### ❌ BAD: Type-based Flat Structure
Avoid scattering related logic across different top-level folders.

```
// src/controllers/users.controller.ts
// src/services/users.service.ts
```

### Naming Conventions
Follow standard TypeScript conventions for clarity:
*   **Files/Folders**: `kebab-case` (e.g., `user-profile.module.ts`)
*   **Classes**: `PascalCase` (e.g., `UsersService`, `CreateUserDto`)
*   **Interfaces**: `IPascalCase` (e.g., `IUserRepository`)
*   **Functions/Methods**: `camelCase` (e.g., `createUser`, `findAllUsers`)
*   **Constants**: `UPPER_SNAKE_CASE` (e.g., `JWT_SECRET`)

## 2. Type Safety and Strictness

Always use explicit types. Avoid `any`. Enable strict TypeScript in `tsconfig.json`.

### ✅ GOOD: Explicit Types
Every variable, parameter, and return value must have an explicit type.

```typescript
interface IUser { id: string; name: string; email: string; }
async function fetchUserById(id: string): Promise<IUser | null> {
  const user: IUser | undefined = await this.userRepository.findOne(id);
  return user ?? null;
}
```

### ❌ BAD: Implicit `any`
Leads to runtime errors and defeats TypeScript's purpose.

```typescript
function fetchUserById(id) { // id is implicitly 'any'
  const user = this.userRepository.findOne(id);
  return user;
}
```

## 3. Common Patterns

### Dependency Injection (DI)
Leverage NestJS's DI system for loose coupling and testability.

### ✅ GOOD: Constructor Injection
Always inject dependencies via the constructor.

```typescript
@Injectable()
export class UsersService {
  constructor(private readonly userRepository: IUserRepository) {}
  async findAll(): Promise<IUser[]> { return this.userRepository.findAll(); }
}
```

### ❌ BAD: Manual Instantiation
Avoid `new` keyword for services/providers.

```typescript
const userService = new UsersService(); // Breaks DI and testability
```

### Data Transfer Objects (DTOs)
Use DTOs with `class-validator` for all incoming request bodies and query parameters.

### ✅ GOOD: Validated DTOs
Ensure data integrity at the edge of your application.

```typescript
// src/modules/users/dtos/create-user.dto.ts
import { IsEmail, IsString, MinLength } from 'class-validator';
export class CreateUserDto {
  @IsString() @MinLength(3) name: string;
  @IsEmail() email: string;
  @IsString() @MinLength(8) password: string;
}
// src/modules/users/controllers/users.controller.ts
@Post()
async createUser(@Body() createUserDto: CreateUserDto): Promise<IUser> {
  return this.userService.create(createUserDto);
}
```

### ❌ BAD: Direct Request Body Usage
Unvalidated data is a security risk.

```typescript
@Post()
async createUser(@Body() body: any): Promise<IUser> { /* ... */ }
```

### Controllers and Services
Controllers handle HTTP requests and delegate business logic to services. Services contain the core business logic and interact with data layers.

### ✅ GOOD: Lean Controllers, Rich Services
Controllers should be thin, focusing on request/response.

```typescript
// src/modules/users/controllers/users.controller.ts
@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}
  @Get(':id')
  async findOne(@Param('id') id: string): Promise<IUser> {
    return this.usersService.findById(id);
  }
}
// src/modules/users/services/users.service.ts
@Injectable()
export class UsersService {
  constructor(private readonly userRepository: IUserRepository) {}
  async findById(id: string): Promise<IUser> {
    const user = await this.userRepository.findOne(id);
    if (!user) { throw new NotFoundException(`User ID "${id}" not found.`); }
    return user;
  }
}
```

### ❌ BAD: Business Logic in Controllers
Makes controllers hard to test and re-use.

```typescript
@Controller('users')
export class UsersController {
  constructor(private readonly userRepository: IUserRepository) {}
  @Get(':id')
  async findOne(@Param('id') id: string): Promise<IUser> {
    const user = await this.userRepository.findOne(id); // Logic here
    if (!user) { throw new NotFoundException(`User ID "${id}" not found.`); }
    return user;
  }
}
```

## 4. Error Handling

Centralize error handling using Exception Filters.

### ✅ GOOD: Global Exception Filters
Catch and format all unhandled exceptions consistently.

```typescript
// src/shared/common/filters/http-exception.filter.ts
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp(); const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>(); const status = exception.getStatus();
    response.status(status).json({
      statusCode: status, timestamp: new Date().toISOString(), path: request.url,
      message: exception.message,
    });
  }
}
// src/main.ts
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter()); // Apply globally
  await app.listen(3000);
}
```

### ❌ BAD: `try/catch` in Every Method
Leads to boilerplate and inconsistent error responses.

```typescript
@Get(':id')
async findOne(@Param('id') id: string): Promise<IUser> {
  try { return await this.usersService.findById(id); }
  catch (error) { throw new HttpException('Failed', HttpStatus.INTERNAL_SERVER_ERROR); }
}
```

## 5. Security Best Practices

### Guards for Authorization
Use `Guards` for declarative route protection.

### ✅ GOOD: Role-Based Access Control (RBAC)
```typescript
// src/modules/auth/guards/roles.guard.ts
@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}
  canActivate(context: ExecutionContext): boolean {
    const requiredRoles = this.reflector.getAllAndOverride<UserRole[]>(ROLES_KEY, [
      context.getHandler(), context.getClass(),
    ]);
    if (!requiredRoles) { return true; }
    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.some((role) => user.roles?.includes(role));
  }
}
// src/modules/users/controllers/users.controller.ts
@Controller('users')
@UseGuards(JwtAuthGuard, RolesGuard) // Apply guards
export class UsersController {
  @Get() @Roles(UserRole.Admin) // Require Admin role
  async findAll(): Promise<IUser[]> { return this.usersService.findAll(); }
}
```

### Environment Variables
Manage configuration securely using `@nestjs/config`.

### ✅ GOOD: `ConfigModule`
```typescript
// src/app.module.ts
@Module({
  imports: [ConfigModule.forRoot({ isGlobal: true, envFilePath: `.env.${process.env.NODE_ENV}` })],
})
export class AppModule {}
// In a service
@Injectable()
export class DatabaseService {
  constructor(private configService: ConfigService) {
    const dbHost = this.configService.get<string>('DATABASE_HOST');
  }
}
```

### ❌ BAD: Hardcoding Secrets
Never hardcode sensitive information.

```typescript
const JWT_SECRET = 'super-secret-key'; // BAD
```

## 6. Performance Considerations

### Fastify Adapter
Use Fastify for improved performance over Express.

### ✅ GOOD: Fastify Integration
```typescript
// src/main.ts
async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule, new FastifyAdapter() // Use Fastify
  );
  await app.listen(3000);
}
bootstrap();
```

### Caching
Implement caching for frequently accessed, slow-changing data.

### ✅ GOOD: `CacheModule`
```typescript
// src/app.module.ts
@Module({
  imports: [CacheModule.register({ store: redisStore, host: 'localhost', port: 6379, ttl: 300 })],
})
export class AppModule {}
// In a service method
@Get() @UseInterceptors(CacheInterceptor) @CacheKey('all_users') @CacheTTL(60)
async findAll(): Promise<IUser[]> { return this.usersService.findAll(); }
```

## 7. Testing

Prioritize unit tests for services and e2e tests for controllers.

### ✅ GOOD: Unit Testing Services
Mock external

© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc

Смотрите также

Спонсоры проекта

Компании, которые помогают держать аналитику открытой