swagger.ts•5.51 kB
/**
* Swagger configuration for the News Aggregator API
*/
import swaggerJSDoc from 'swagger-jsdoc';
import { version } from '../../package.json';
const options: swaggerJSDoc.Options = {
definition: {
openapi: '3.0.0',
info: {
title: 'News Aggregator API',
version,
description: 'A RESTful API for accessing and filtering news articles with MCP architecture',
license: {
name: 'ISC',
url: 'https://opensource.org/licenses/ISC',
},
contact: {
name: 'API Support',
email: 'support@example.com',
},
},
servers: [
{
url: '/api',
description: 'Development server',
},
],
tags: [
{
name: 'News',
description: 'News articles endpoints',
},
{
name: 'Cache',
description: 'Cache management endpoints',
},
],
components: {
schemas: {
Article: {
type: 'object',
required: ['id', 'uuid', 'title', 'url', 'source', 'publishedAt', 'categories', 'language'],
properties: {
id: {
type: 'integer',
description: 'Unique identifier for the article',
},
uuid: {
type: 'string',
description: 'UUID from the news source',
},
title: {
type: 'string',
description: 'Article title',
},
description: {
type: 'string',
description: 'Article description or summary',
nullable: true,
},
url: {
type: 'string',
description: 'URL to the full article',
},
imageUrl: {
type: 'string',
description: 'URL to the article image',
nullable: true,
},
source: {
type: 'string',
description: 'Source of the article (e.g., CNN, BBC)',
},
publishedAt: {
type: 'string',
format: 'date-time',
description: 'Publication date and time',
},
categories: {
type: 'string',
description: 'Comma-separated list of categories',
},
language: {
type: 'string',
description: 'Article language code (e.g., en, es)',
},
readCount: {
type: 'integer',
description: 'Number of times the article has been read',
},
relevanceScore: {
type: 'number',
format: 'float',
description: 'Article relevance score (0-1)',
nullable: true,
},
sentiment: {
type: 'number',
format: 'float',
description: 'Article sentiment score (-1 to 1)',
nullable: true,
},
},
},
ErrorResponse: {
type: 'object',
required: ['success', 'error'],
properties: {
success: {
type: 'boolean',
example: false,
},
error: {
type: 'string',
example: 'Error message description',
},
},
},
SuccessResponse: {
type: 'object',
required: ['success', 'data'],
properties: {
success: {
type: 'boolean',
example: true,
},
data: {
type: 'object',
description: 'Response data object',
},
},
},
},
parameters: {
limitParam: {
name: 'limit',
in: 'query',
description: 'Maximum number of items to return',
required: false,
schema: {
type: 'integer',
default: 10,
},
},
offsetParam: {
name: 'offset',
in: 'query',
description: 'Number of items to skip',
required: false,
schema: {
type: 'integer',
default: 0,
},
},
sortParam: {
name: 'sort',
in: 'query',
description: 'Sort field (e.g., publishedAt, relevanceScore)',
required: false,
schema: {
type: 'string',
default: 'publishedAt',
},
},
orderParam: {
name: 'order',
in: 'query',
description: 'Sort order (asc or desc)',
required: false,
schema: {
type: 'string',
enum: ['asc', 'desc'],
default: 'desc',
},
},
},
responses: {
NotFound: {
description: 'Resource not found',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/ErrorResponse',
},
},
},
},
ServerError: {
description: 'Internal server error',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/ErrorResponse',
},
},
},
},
},
},
},
apis: ['./src/routes/*.ts', './src/controllers/*.ts'],
};
export const swaggerSpec = swaggerJSDoc(options);