news.controller.ts•9.03 kB
/**
* Controller for news-related endpoints
*/
import { Request, Response } from 'express';
import { NewsService } from '../services/news.service';
import { logger } from '../utils/logger';
import { NewsApiParams, SourcesApiParams } from '../models/news.model';
export class NewsController {
private newsService: NewsService;
constructor() {
this.newsService = new NewsService();
}
/**
* Get top news articles with optional filtering
* @param req Express request object
* @param res Express response object
*/
async getTopNews(req: Request, res: Response): Promise<void> {
try {
// Extract query parameters (excluding api_token which is handled by the service)
const params: Omit<NewsApiParams, 'api_token'> = {
search: req.query.search as string,
search_fields: req.query.search_fields as string,
locale: req.query.locale as string,
categories: req.query.categories as string,
exclude_categories: req.query.exclude_categories as string,
domains: req.query.domains as string,
exclude_domains: req.query.exclude_domains as string,
source_ids: req.query.source_ids as string,
exclude_source_ids: req.query.exclude_source_ids as string,
language: req.query.language as string,
published_before: req.query.published_before as string,
published_after: req.query.published_after as string,
published_on: req.query.published_on as string,
sort: req.query.sort as 'published_at' | 'relevance_score',
limit: req.query.limit ? parseInt(req.query.limit as string, 10) : undefined,
page: req.query.page ? parseInt(req.query.page as string, 10) : undefined
};
// Filter out undefined values
Object.keys(params).forEach(key => {
if (params[key as keyof typeof params] === undefined) {
delete params[key as keyof typeof params];
}
});
logger.info('Processing top news request with params:', params);
const newsData = await this.newsService.getTopNews(params);
res.status(200).json({
success: true,
data: newsData
});
} catch (error) {
logger.error('Error in getTopNews controller:', error);
res.status(500).json({
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
});
}
}
/**
* Get all news articles with optional filtering and advanced search
* @param req Express request object
* @param res Express response object
*/
async getAllNews(req: Request, res: Response): Promise<void> {
try {
// Extract query parameters (excluding api_token which is handled by the service)
const params: Omit<NewsApiParams, 'api_token'> = {
search: req.query.search as string,
search_fields: req.query.search_fields as string,
locale: req.query.locale as string,
categories: req.query.categories as string,
exclude_categories: req.query.exclude_categories as string,
domains: req.query.domains as string,
exclude_domains: req.query.exclude_domains as string,
source_ids: req.query.source_ids as string,
exclude_source_ids: req.query.exclude_source_ids as string,
language: req.query.language as string,
published_before: req.query.published_before as string,
published_after: req.query.published_after as string,
published_on: req.query.published_on as string,
sort: req.query.sort as 'published_at' | 'relevance_score',
limit: req.query.limit ? parseInt(req.query.limit as string, 10) : undefined,
page: req.query.page ? parseInt(req.query.page as string, 10) : undefined
};
// Filter out undefined values
Object.keys(params).forEach(key => {
if (params[key as keyof typeof params] === undefined) {
delete params[key as keyof typeof params];
}
});
logger.info('Processing all news request with params:', params);
const newsData = await this.newsService.getAllNews(params);
res.status(200).json({
success: true,
data: newsData
});
} catch (error) {
logger.error('Error in getAllNews controller:', error);
res.status(500).json({
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
});
}
}
/**
* Get similar news articles to a specific article by UUID
* @param req Express request object with UUID as a route parameter
* @param res Express response object
*/
async getSimilarNews(req: Request, res: Response): Promise<void> {
try {
const { uuid } = req.params;
// Extract query parameters (excluding api_token which is handled by the service)
const params: Omit<NewsApiParams, 'api_token'> = {
categories: req.query.categories as string,
exclude_categories: req.query.exclude_categories as string,
domains: req.query.domains as string,
exclude_domains: req.query.exclude_domains as string,
source_ids: req.query.source_ids as string,
exclude_source_ids: req.query.exclude_source_ids as string,
language: req.query.language as string,
published_before: req.query.published_before as string,
published_after: req.query.published_after as string,
published_on: req.query.published_on as string,
limit: req.query.limit ? parseInt(req.query.limit as string, 10) : undefined,
page: req.query.page ? parseInt(req.query.page as string, 10) : undefined
};
// Filter out undefined values
Object.keys(params).forEach(key => {
if (params[key as keyof typeof params] === undefined) {
delete params[key as keyof typeof params];
}
});
logger.info(`Processing similar news request for UUID ${uuid} with params:`, params);
const newsData = await this.newsService.getSimilarNews(uuid, params);
res.status(200).json({
success: true,
data: newsData
});
} catch (error) {
logger.error('Error in getSimilarNews controller:', error);
const statusCode = error instanceof Error && error.message.includes('Invalid UUID format') ? 400 : 500;
res.status(statusCode).json({
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
});
}
}
/**
* Get a specific news article by UUID
* @param req Express request object with UUID as a route parameter
* @param res Express response object
*/
async getNewsByUuid(req: Request, res: Response): Promise<void> {
try {
const { uuid } = req.params;
logger.info(`Processing news article request for UUID ${uuid}`);
const article = await this.newsService.getNewsByUuid(uuid);
res.status(200).json({
success: true,
data: article
});
} catch (error) {
logger.error('Error in getNewsByUuid controller:', error);
// Handle different error types with appropriate status codes
let statusCode = 500;
if (error instanceof Error) {
if (error.message.includes('Invalid UUID format')) {
statusCode = 400; // Bad Request
} else if (error.message.includes('404')) {
statusCode = 404; // Not Found
}
}
res.status(statusCode).json({
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
});
}
}
/**
* Get available news sources with optional filtering
* @param req Express request object
* @param res Express response object
*/
async getNewsSources(req: Request, res: Response): Promise<void> {
try {
// Extract query parameters (excluding api_token which is handled by the service)
const params: Omit<SourcesApiParams, 'api_token'> = {
categories: req.query.categories as string,
exclude_categories: req.query.exclude_categories as string,
language: req.query.language as string,
page: req.query.page ? parseInt(req.query.page as string, 10) : undefined
};
// Filter out undefined values
Object.keys(params).forEach(key => {
if (params[key as keyof typeof params] === undefined) {
delete params[key as keyof typeof params];
}
});
logger.info('Processing news sources request with params:', params);
const sourcesData = await this.newsService.getNewsSources(params);
res.status(200).json({
success: true,
data: sourcesData
});
} catch (error) {
logger.error('Error in getNewsSources controller:', error);
res.status(500).json({
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred'
});
}
}
}