Başlangıç

Base Response Rules

NestJS + Swagger + Custom Decorator Standardı


Amaç

Bu rehber, projedeki tüm modüller için tutarlı, okunabilir ve otomatik Swagger uyumlu API dokümantasyonu oluşturmayı amaçlar. Her modülün controller’ları ortak bir şablonla belgelenir ve tekrar eden Swagger açıklamaları özel decorator fonksiyonlarıyla yönetilir.


1. Mimarinin Temeli

Her API yanıtı interceptor tarafından BaseResponseDto formatına dönüştürülür:

{
  "isSuccess": true,
  "statusCode": 200,
  "data": {...},
  "errors": [],
  "timestamp": "2025-11-06T10:00:00.000Z"
}

Katmanlar:

KatmanAçıklama
ServiceSadece iş mantığı. DTO döndürür.
ControllerEndpoint tanımları, özel decorator kullanır.
DecoratorsSwagger açıklamalarını tek merkezden yönetir.
InterceptorBaseResponseDto formatına dönüştürür.

2. Base DTO Standartları

BaseResponseDto<T>

Tüm yanıtların ortak formatı:

{
  isSuccess: boolean;
  statusCode: number;
  data?: T;
  errors?: string[];
  timestamp: string;
}

PaginatedResponseDto<T>

Sayfalama yapılan endpoint’ler için standart yapı:

{
  list: T[];
  pagination: {
    currentPage: number;
    totalPages: number;
    totalItems: number;
    itemsPerPage: number;
    hasNextPage?: boolean;
    hasPrevPage?: boolean;
  }
}

3. Ortak Decorator Yapısı

Tüm modüller bu üç ana decorator’ı kullanır:

DecoratorAmaç
@ApiBaseResponseTekil veya liste veri yanıtlarını açıklar
@ApiPaginatedResponseSayfalama yapısı içeren endpoint’ler için
@ApiErrorResponseHatalı yanıtları örnekler

Ortak index dosyası:

export * from './api-base-response.decorator';
export * from './api-error-response.decorator';
export * from './api-paginated-response.decorator';

4. Modül Bazlı Özel Decorator’lar

Her modülün decorators/ klasöründe, o modüle özel API endpoint’leri belgelenir.

Örnek: src/live-stream/decorators/api-create-ban.decorator.ts

import { applyDecorators } from '@nestjs/common';
import { ApiBearerAuth, ApiOperation } from '@nestjs/swagger';
import { ApiBaseResponse, ApiErrorResponse } from '../../common/decorators';
import { StreamBanResponseDto } from '../dto/stream-ban-response.dto';

export function ApiCreateBan() {
  return applyDecorators(
    ApiBearerAuth('JWT-auth'),
    ApiOperation({
      summary: 'Yeni ban oluştur',
      description: 'Kullanıcıyı belirli bir yayından veya yayıncının tüm yayınlarından banlar',
    }),
    ApiBaseResponse({
      status: 201,
      description: 'Ban başarıyla oluşturuldu',
      type: StreamBanResponseDto,
    }),
    ApiErrorResponse({
      status: 400,
      description: 'Geçersiz istek veya validation hatası',
      exampleErrors: ['Invalid targetUserId', 'Missing scope'],
    }),
    ApiErrorResponse({
      status: 409,
      description: 'Aynı kapsamda ban zaten mevcut',
      exampleErrors: ['A ban already exists for this user'],
    }),
  );
}

5. Önerilen Modül Klasör Yapısı

src/
 ├── common/
 │    ├── decorators/
 │    │    ├── api-base-response.decorator.ts
 │    │    ├── api-error-response.decorator.ts
 │    │    ├── api-paginated-response.decorator.ts
 │    │    └── index.ts
 │    └── dto/
 │         ├── pagination.dto.ts
 │         └── paginated-response.dto.ts
 ├── <feature-module>/
 │    ├── dto/
 │    ├── schemas/
 │    ├── decorators/
 │    │    ├── api-create.decorator.ts
 │    │    ├── api-get.decorator.ts
 │    │    ├── api-get-detail.decorator.ts
 │    │    ├── api-update.decorator.ts
 │    │    ├── api-delete.decorator.ts
 │    │    └── index.ts
 │    ├── <feature>.service.ts
 │    └── <feature>.controller.ts

6. Controller Şablonu

Her modülün controller’ı benzer görünür:

@ApiTags('product')
@Controller('product')
export class ProductController {
  constructor(private readonly productService: ProductService) {}

  @Post()
  @ApiCreateProduct()
  create(@Body() dto: CreateProductDto, @CurrentUser() user: JwtPayload) {
    return this.productService.create(dto, user._id);
  }

  @Get()
  @ApiGetProducts()
  findAll(@Query() query: ProductQueryDto) {
    return this.productService.findAll(query);
  }

  @Get(':id')
  @ApiGetProductDetail()
  findOne(@Param('id') id: string) {
    return this.productService.findOne(id);
  }

  @Patch(':id')
  @ApiUpdateProduct()
  update(@Param('id') id: string, @Body() dto: UpdateProductDto) {
    return this.productService.update(id, dto);
  }

  @Delete(':id')
  @ApiDeleteProduct()
  remove(@Param('id') id: string) {
    return this.productService.remove(id);
  }
}

7. Yeni Modül İçin Adımlar

1️⃣ common/decorators klasörünü tüm modüller kullanır. 2️⃣ Her modül kendi decorators/ klasörünü oluşturur. 3️⃣ Her endpoint türü için (create, get, update, delete, check, revoke vs.) ayrı decorator hazırlanır. 4️⃣ Controller’da Swagger açıklamaları bu decorator’lar üzerinden yönetilir. 5️⃣ Servis sadece DTO döndürür — interceptor BaseResponseDto ekler.


8. Swagger’da Sonuç

Swagger UI’da tüm endpoint’ler şu şekilde görünür:

  • ✅ Başarılı yanıt (data veya list + pagination)
  • ⚠️ Hatalı yanıt örnekleri (ApiErrorResponse)
  • 📜 Authorization bilgisi (ApiBearerAuth)
  • 🔧 Query ve parametre açıklamaları (ApiQuery)

Her endpoint, “summary” ve “description” alanlarında modüle özel net açıklama içerir.


9. Yapay Zeka Prompt Şablonu

Aşağıdaki prompt’u kullanarak bu mimaride yeni modüller oluşturabilirsin. Sadece modülün adını, DTO’ları ve özelliklerini tanımlaman yeterli 👇


Prompt Şablonu

Görev:
NestJS + Swagger altyapısında, BaseResponseDto ve custom API decorator mimarisini kullanan yeni bir modül oluştur.

Modül adı: [örnek: Product]
İşlev: [örnek: ürün yönetimi]
Endpoint’ler:
- create (POST)
- get all (GET)
- get by id (GET/:id)
- update (PATCH/:id)
- delete (DELETE/:id)

İstek:
1. ProductService ve ProductController’ı oluştur.
2. Her endpoint için özel Swagger decorator (api-create-product.decorator.ts vb.) yaz.
3. @ApiBaseResponse, @ApiErrorResponse, @ApiPaginatedResponse yapısını uygula.
4. Dosya yapısını ve import path’lerini common/decorators mimarisine göre düzenle.
5. Controller’ı sadece DTO döndürecek şekilde yaz (BaseResponseInterceptor kullanılacak).

Sonuç

Bu yapı sayesinde:

  • Her modül tek tip API standardına uyar.
  • Swagger dokümantasyonu manuel kod yazmadan üretilir.
  • common/decorators sayesinde sistem ölçeklenebilir hale gelir.
  • Yeni modüller (örneğin UserBan, Order, Inventory, Comment, Notification) birkaç dakika içinde eklenebilir.

On this page