mirror of
https://gitlab.com/foxixus/neomovies-api.git
synced 2025-10-28 01:48:51 +05:00
Update 3 files
- /api/index.js - /src/index.js - /vercel.json
This commit is contained in:
3
api/index.js
Normal file
3
api/index.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
const app = require('../src/index');
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
171
src/index.js
171
src/index.js
@@ -7,12 +7,11 @@ const TMDBClient = require('./config/tmdb');
|
|||||||
const healthCheck = require('./utils/health');
|
const healthCheck = require('./utils/health');
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
const port = process.env.PORT || 3000;
|
|
||||||
|
|
||||||
// Определяем базовый URL для документации
|
// Определяем базовый URL для документации
|
||||||
const BASE_URL = process.env.NODE_ENV === 'production'
|
const BASE_URL = process.env.NODE_ENV === 'production'
|
||||||
? 'https://neomovies-api.vercel.app'
|
? 'https://neomovies-api.vercel.app'
|
||||||
: `http://localhost:${port}`;
|
: 'http://localhost:3000';
|
||||||
|
|
||||||
// Swagger configuration
|
// Swagger configuration
|
||||||
const swaggerOptions = {
|
const swaggerOptions = {
|
||||||
@@ -30,8 +29,8 @@ const swaggerOptions = {
|
|||||||
servers: [
|
servers: [
|
||||||
{
|
{
|
||||||
url: BASE_URL,
|
url: BASE_URL,
|
||||||
description: process.env.NODE_ENV === 'production' ? 'Production server' : 'Development server',
|
description: process.env.NODE_ENV === 'production' ? 'Production server' : 'Development server'
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
tags: [
|
tags: [
|
||||||
{
|
{
|
||||||
@@ -87,127 +86,18 @@ const swaggerOptions = {
|
|||||||
description: 'Сообщение об ошибке'
|
description: 'Сообщение об ошибке'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
Health: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
status: {
|
|
||||||
type: 'string',
|
|
||||||
enum: ['healthy', 'unhealthy'],
|
|
||||||
description: 'Общий статус API'
|
|
||||||
},
|
|
||||||
version: {
|
|
||||||
type: 'string',
|
|
||||||
description: 'Версия API'
|
|
||||||
},
|
|
||||||
uptime: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
seconds: {
|
|
||||||
type: 'integer',
|
|
||||||
description: 'Время работы в секундах'
|
|
||||||
},
|
|
||||||
formatted: {
|
|
||||||
type: 'string',
|
|
||||||
description: 'Отформатированное время работы'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tmdb: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
status: {
|
|
||||||
type: 'string',
|
|
||||||
enum: ['ok', 'error'],
|
|
||||||
description: 'Статус подключения к TMDB'
|
|
||||||
},
|
|
||||||
responseTime: {
|
|
||||||
type: 'integer',
|
|
||||||
description: 'Время ответа TMDB в мс'
|
|
||||||
},
|
|
||||||
error: {
|
|
||||||
type: 'string',
|
|
||||||
description: 'Сообщение об ошибке, если есть'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
memory: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
heapTotal: {
|
|
||||||
type: 'integer',
|
|
||||||
description: 'Общий размер кучи (MB)'
|
|
||||||
},
|
|
||||||
heapUsed: {
|
|
||||||
type: 'integer',
|
|
||||||
description: 'Использованный размер кучи (MB)'
|
|
||||||
},
|
|
||||||
rss: {
|
|
||||||
type: 'integer',
|
|
||||||
description: 'Resident Set Size (MB)'
|
|
||||||
},
|
|
||||||
memoryUsage: {
|
|
||||||
type: 'integer',
|
|
||||||
description: 'Процент использования памяти'
|
|
||||||
},
|
|
||||||
system: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
total: {
|
|
||||||
type: 'integer',
|
|
||||||
description: 'Общая память системы (MB)'
|
|
||||||
},
|
|
||||||
free: {
|
|
||||||
type: 'integer',
|
|
||||||
description: 'Свободная память системы (MB)'
|
|
||||||
},
|
|
||||||
usage: {
|
|
||||||
type: 'integer',
|
|
||||||
description: 'Процент использования системной памяти'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
system: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
platform: {
|
|
||||||
type: 'string',
|
|
||||||
description: 'Операционная система'
|
|
||||||
},
|
|
||||||
arch: {
|
|
||||||
type: 'string',
|
|
||||||
description: 'Архитектура процессора'
|
|
||||||
},
|
|
||||||
nodeVersion: {
|
|
||||||
type: 'string',
|
|
||||||
description: 'Версия Node.js'
|
|
||||||
},
|
|
||||||
cpuUsage: {
|
|
||||||
type: 'number',
|
|
||||||
description: 'Загрузка CPU'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
timestamp: {
|
|
||||||
type: 'string',
|
|
||||||
format: 'date-time',
|
|
||||||
description: 'Время проверки'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
apis: [path.join(__dirname, 'routes', '*.js'), path.join(__dirname, 'index.js')]
|
apis: [path.join(__dirname, 'routes', '*.js'), __filename]
|
||||||
};
|
};
|
||||||
|
|
||||||
const swaggerDocs = swaggerJsdoc(swaggerOptions);
|
const swaggerDocs = swaggerJsdoc(swaggerOptions);
|
||||||
|
|
||||||
// CORS configuration
|
// CORS configuration
|
||||||
app.use(cors({
|
app.use(cors({
|
||||||
origin: true, // Разрешаем все origins в development
|
origin: true,
|
||||||
credentials: true,
|
credentials: true,
|
||||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
||||||
allowedHeaders: ['X-Requested-With', 'Content-Type', 'Authorization', 'Accept']
|
allowedHeaders: ['X-Requested-With', 'Content-Type', 'Authorization', 'Accept']
|
||||||
@@ -256,21 +146,52 @@ app.use('/movies', require('./routes/movies'));
|
|||||||
* content:
|
* content:
|
||||||
* application/json:
|
* application/json:
|
||||||
* schema:
|
* schema:
|
||||||
* $ref: '#/components/schemas/Health'
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* status:
|
||||||
|
* type: string
|
||||||
|
* enum: [ok, error]
|
||||||
|
* tmdb:
|
||||||
|
* type: object
|
||||||
|
* properties:
|
||||||
|
* status:
|
||||||
|
* type: string
|
||||||
|
* enum: [ok, error]
|
||||||
*/
|
*/
|
||||||
app.get('/health', async (req, res) => {
|
app.get('/health', async (req, res) => {
|
||||||
const health = await healthCheck.getFullHealth(req.tmdb);
|
try {
|
||||||
res.json(health);
|
const health = await healthCheck.getFullHealth(req.tmdb);
|
||||||
|
res.json(health);
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({
|
||||||
|
status: 'error',
|
||||||
|
error: error.message
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Error handling
|
// Error handling
|
||||||
app.use((err, req, res, next) => {
|
app.use((err, req, res, next) => {
|
||||||
console.error(err.stack);
|
console.error('Error:', err);
|
||||||
res.status(500).json({ error: 'Something went wrong!' });
|
res.status(500).json({
|
||||||
|
error: 'Internal Server Error',
|
||||||
|
message: process.env.NODE_ENV === 'development' ? err.message : undefined
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Start server
|
// Handle 404
|
||||||
app.listen(port, () => {
|
app.use((req, res) => {
|
||||||
console.log(`Server is running on port ${port}`);
|
res.status(404).json({ error: 'Not Found' });
|
||||||
console.log(`Documentation available at https://neomovies-api.vercel.app/api-docs`);
|
});
|
||||||
});
|
|
||||||
|
// Export the Express API
|
||||||
|
module.exports = app;
|
||||||
|
|
||||||
|
// Start server only in development
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
const port = process.env.PORT || 3000;
|
||||||
|
app.listen(port, () => {
|
||||||
|
console.log(`Server is running on port ${port}`);
|
||||||
|
console.log(`Documentation available at http://localhost:${port}/api-docs`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
39
vercel.json
39
vercel.json
@@ -2,50 +2,17 @@
|
|||||||
"version": 2,
|
"version": 2,
|
||||||
"builds": [
|
"builds": [
|
||||||
{
|
{
|
||||||
"src": "src/index.js",
|
"src": "api/index.js",
|
||||||
"use": "@vercel/node"
|
"use": "@vercel/node"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"routes": [
|
"routes": [
|
||||||
{
|
|
||||||
"src": "/api-docs/(.*)",
|
|
||||||
"headers": {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
||||||
"Access-Control-Allow-Headers": "X-Requested-With, Content-Type, Accept"
|
|
||||||
},
|
|
||||||
"dest": "/src/index.js"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "/movies/(.*)",
|
|
||||||
"headers": {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
||||||
"Access-Control-Allow-Headers": "X-Requested-With, Content-Type, Accept"
|
|
||||||
},
|
|
||||||
"dest": "/src/index.js"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "/health",
|
|
||||||
"headers": {
|
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
"Access-Control-Allow-Methods": "GET, OPTIONS",
|
|
||||||
"Access-Control-Allow-Headers": "X-Requested-With, Content-Type, Accept"
|
|
||||||
},
|
|
||||||
"dest": "/src/index.js"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"src": "/(.*)",
|
"src": "/(.*)",
|
||||||
"headers": {
|
"dest": "/api/index.js"
|
||||||
"Access-Control-Allow-Origin": "*",
|
|
||||||
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
||||||
"Access-Control-Allow-Headers": "X-Requested-With, Content-Type, Accept"
|
|
||||||
},
|
|
||||||
"dest": "/src/index.js"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"env": {
|
"env": {
|
||||||
"NODE_ENV": "production",
|
"NODE_ENV": "production"
|
||||||
"TMDB_ACCESS_TOKEN": "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJkOWRlZTY5ZjYzNzYzOGU2MjY5OGZhZGY0ZjhhYTNkYyIsInN1YiI6IjY1OTVkNmM5ODY5ZTc1NzJmOTY1MjZiZiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.Wd_tBYGkAoGPVHq3A5DwV1iLs_eGvH3RRz86ghJTmU8"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user