Commit c8515eeb authored by Kulpybaev Ilyas's avatar Kulpybaev Ilyas

Webinar-swagger

parent 84aa15f2
This diff is collapsed.
{
"name": "node_template",
"version": "1.0.0",
"version": "2.1.5",
"description": "",
"main": "index.js",
"scripts": {
......@@ -21,6 +21,8 @@
"multer": "^1.4.5-lts.1",
"mysql2": "^3.9.4",
"reflect-metadata": "^0.2.1",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.0",
"ts-node": "^10.9.1",
"tslib": "^2.6.0",
"typeorm": "^0.3.20",
......@@ -32,6 +34,8 @@
"@types/express": "^4.17.17",
"@types/multer": "^1.4.11",
"@types/node": "^20.4.2",
"@types/swagger-jsdoc": "^6.0.4",
"@types/swagger-ui-express": "^4.1.6",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.45.0",
......
......@@ -3,6 +3,8 @@ import { Application, RequestHandler } from 'express';
import { AppInit } from './interfaces/AppInit.interface';
import { IRoute } from './interfaces/IRoute.interface';
import { appDataSource } from '@/config/dataSource';
import swaggerUi from 'swagger-ui-express';
import { specs } from '@/config/swagger';
class App {
public app: Application;
......@@ -28,6 +30,8 @@ class App {
private initAssets() {
this.app.use(express.json());
this.app.use(express.static('public'));
this.app.use('/api-docs', swaggerUi.serve);
this.app.get('/api-docs', swaggerUi.setup(specs));
}
public async listen() {
await appDataSource.initialize();
......
import swaggerJsdoc from 'swagger-jsdoc';
import {version} from '../../package.json';
const options = {
swaggerDefinition: {
openapi: '3.0.0',
info: {
title: 'Shop-API',
version: version,
description: 'Shop REST API'
},
servers: [
{
url: 'http://localhost:8000'
}
],
components: {
schemas: {
ProductDto: {
type: 'object',
properties: {
title: {
type: 'string',
description: 'Название продукта'
},
description: {
type: 'string',
description: 'Описание продукта'
},
price: {
type: 'number',
description: 'Цена продукта'
},
image: {
type: 'file',
description: 'Картинка продукта',
format: 'binary'
},
categoryId: {
type: 'number',
description: 'ID категории продукта'
}
},
required: ['title', 'price', 'categoryId']
},
CategoryDto: {
type: 'object',
properties: {
title: {
type: 'string',
description: 'Название категории'
},
description: {
type: 'string',
description: 'Описание категории'
},
},
required: ['title']
},
StatusEnum: {
type: 'string',
enum: ['success', 'error', 'loading'],
description: 'Статус оплаты'
}
}
}
},
apis: ['src/controllers/*.ts']
};
export const specs = swaggerJsdoc(options);
\ No newline at end of file
......@@ -3,6 +3,8 @@ import { RequestHandler } from 'express';
import { plainToInstance } from 'class-transformer';
import { RegisterUserDto } from '@/dto/register-user.dto';
import { SignInUserDto } from '@/dto/sign-in-user.dto';
import { validate } from 'class-validator';
import { formatErrors } from '@/helpers/formatErrors';
export class AuthController {
private service: AuthService;
......@@ -14,6 +16,7 @@ export class AuthController {
signIn: RequestHandler = async (req, res): Promise<void> => {
try {
const signInUserDto = plainToInstance(SignInUserDto, req.body);
const user = await this.service.signIn(signInUserDto);
res.send(user);
} catch (e) {
......@@ -24,6 +27,15 @@ export class AuthController {
register: RequestHandler = async (req, res): Promise<void> => {
try {
const registerUserDto = plainToInstance(RegisterUserDto, req.body);
const errors = await validate(registerUserDto, {
whitelist: true,
validationError: { target: false, value: false },
});
if (errors.length > 0) {
res.status(400).send(formatErrors(errors));
return;
}
const user = await this.service.register(registerUserDto);
res.send(user);
} catch (e) {
......
......@@ -10,11 +10,43 @@ export class CategoryController {
this.service = new CategoryService();
}
/**
* @swagger
* /categories:
* get:
* summary: Получить список категорий
* tags:
* - Categories
* responses:
* '200':
* description: Успешный запрос, получаем список категорий
* '500':
* description: Внутренняя ошибка сервера
*/
getCategories: RequestHandler = async (req, res): Promise<void> => {
const categories = await this.service.getCategories();
res.send(categories);
};
/**
* @swagger
* /categories:
* post:
* summary: Создать новую категорию
* tags:
* - Categories
* requestBody:
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/CategoryDto'
* responses:
* '200':
* description: Успешный запрос, получаем список категорий
* '500':
* description: Внутренняя ошибка сервера
*/
createCategory: RequestHandler = async (req, res): Promise<void> => {
const categoryDto = plainToInstance(CategoryDto, req.body);
const category = await this.service.createCategory(categoryDto);
......
......@@ -10,11 +10,44 @@ export class ProductController {
this.service = new ProductService();
}
/**
* @swagger
* /products:
* get:
* summary: Получить список продуктов
* tags:
* - Products
* responses:
* '200':
* description: Успешный запрос, получаем список продуктов
* '500':
* description: Внутренняя ошибка сервера
*/
getProducts: RequestHandler = async (req, res): Promise<void> => {
const products = await this.service.getProducts();
res.send(products);
};
/**
* @swagger
* /products/{id}:
* get:
* summary: Получить один продукт
* tags:
* - Products
* parameters:
* - in: path
* name: id
* required: true
* description: ID продукта
* schema:
* type: integer
* responses:
* '200':
* description: Успешный запрос, получаем продукт
* '400':
* description: Неверный запрос, продукт с указанным ID не найден
*/
getProduct: RequestHandler = async (req, res): Promise<void> => {
try {
const product = await this.service.getProduct(Number(req.params.id));
......@@ -24,6 +57,28 @@ export class ProductController {
}
};
/**
* @swagger
* /products:
* post:
* summary: Создать новый продукт
* tags:
* - Products
* requestBody:
* required: true
* content:
* multipart/form-data:
* schema:
* $ref: '#/components/schemas/ProductDto'
* responses:
* '200':
* description: Успешный запрос, создаем новый продукт
* '400':
* description: Ошибка в запросе, сообщение об ошибке
* '500':
* description: Внутренняя ошибка сервера
*/
createProduct: RequestHandler = async (req, res): Promise<void> => {
try {
const productDto = plainToInstance(ProductDto, req.body);
......
......@@ -15,4 +15,8 @@ export class ProductDto {
@IsOptional()
image!: string;
@IsNotEmpty({ message: 'Укажите категорию продукта' })
@IsNumberString({}, { message: 'Укажите корректную категорию' })
categoryId!: number;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment