Стандарты API
Обёртка ответа
typescript
// Все успешные ответы следуют этому формату
interface SuccessResponse<T> {
success: true;
data: T;
meta?: {
pagination?: PaginationMeta;
[key: string]: unknown;
};
}
interface PaginationMeta {
total: number;
page: number;
pageSize: number;
totalPages: number;
hasNext: boolean;
hasPrevious: boolean;
}Примеры
Один элемент
json
{
"success": true,
"data": {
"id": "uuid",
"email": "user@example.com"
}
}Список с пагинацией
json
{
"success": true,
"data": [
{ "id": "uuid1", "name": "Product 1" },
{ "id": "uuid2", "name": "Product 2" }
],
"meta": {
"pagination": {
"total": 100,
"page": 1,
"pageSize": 20,
"totalPages": 5,
"hasNext": true,
"hasPrevious": false
}
}
}Пагинация
typescript
// Offset пагинация с query параметрами: ?page=1&pageSize=20
interface PaginationQuery {
page?: number; // По умолчанию: 1, минимум: 1
pageSize?: number; // По умолчанию: 20, максимум: 100
}
// Использование в контроллере
@Get()
async findAll(
@Query() pagination: PaginationQuery,
): Promise<SuccessResponse<Product[]>> {
const { page = 1, pageSize = 20 } = pagination;
const result = await this.productService.findAll({ page, pageSize });
return {
success: true,
data: result.items,
meta: { pagination: result.pagination },
};
}Фильтрация и сортировка
typescript
// Query параметры для фильтрации
// GET /api/v1/products?status=ACTIVE&categoryId=uuid&minPrice=100&maxPrice=500
// Query параметры для сортировки
// GET /api/v1/products?sortBy=price&sortOrder=asc
interface ProductFilterQuery {
status?: ProductStatus;
categoryId?: string;
minPrice?: number;
maxPrice?: number;
search?: string; // Полнотекстовый поиск по названию/описанию
sortBy?: 'price' | 'name' | 'createdAt';
sortOrder?: 'asc' | 'desc';
}Версионирование API
/api/v1/... ← Текущая версия
В будущем:
/api/v2/... ← Только для критических измененийСтратегия: Версионирование через URL (самый простой способ). Создавать v2 только при неизбежных критических изменениях.
Документация API (Scalar)
Интерактивная документация API с использованием Scalar — современная альтернатива Swagger UI с лучшим UX, тёмной темой и быстрым рендерингом.
Установка
bash
npm install @nestjs/swagger @scalar/nestjs-api-referenceНастройка
typescript
// main.ts
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { apiReference } from '@scalar/nestjs-api-reference';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Спецификация OpenAPI
const config = new DocumentBuilder()
.setTitle('IWM Platform API')
.setDescription('MLM Platform with Investment and Product Marketplaces')
.setVersion('1.0')
.addBearerAuth()
.addTag('auth', 'Authentication endpoints')
.addTag('users', 'User management')
.addTag('mlm', 'MLM/Partner operations')
.addTag('products', 'E-commerce products')
.addTag('orders', 'Order management')
.addTag('investments', 'Investment operations')
.build();
const document = SwaggerModule.createDocument(app, config);
// Scalar UI по адресу /api/docs (заменяет Swagger UI)
app.use('/api/docs', apiReference({
spec: { content: document },
theme: 'purple', // или 'default', 'moon', 'mars'
}));
// Опционально: JSON endpoint для внешних инструментов
app.use('/api/docs/openapi.json', (req, res) => res.json(document));
await app.listen(3000);
}Возможности
| Функция | Описание |
|---|---|
| Try It | Интерактивный конструктор запросов с поддержкой авторизации |
| Search | Полнотекстовый поиск по всем эндпоинтам |
| Dark Mode | Встроенное переключение тем |
| Code Samples | Автогенерируемые примеры на разных языках |
| OpenAPI 3.1 | Полная поддержка спецификации |
Доступ
- Интерактивная документация:
http://localhost:3000/api/docs - OpenAPI JSON:
http://localhost:3000/api/docs/openapi.json