Files
news_service/src/controllers/NewsApiCompatibilityController.js
Weng JinPeng 3d891d781c feat: initialize news service with core functionality
- Add package.json for project configuration and dependencies.
- Implement NewsApplication class to manage service lifecycle and HTTP pipeline.
- Create CategoryCatalog for managing news categories.
- Introduce ServiceConfig for environment variable management.
- Load environment variables from .env files.
- Develop NewsApiCompatibilityController to mimic NewsAPI endpoints.
- Create NewsController for querying and refreshing news data.
- Establish AbstractJsonRepository for JSON storage operations.
- Implement main entry point in index.js to bootstrap the application.
- Create CategoryNewsRepository for category-specific news storage.
- Add ConsoleLogger for structured logging.
- Implement NewsApiClient for fetching articles from NewsAPI.
- Develop NewsRefreshScheduler for scheduling news refresh tasks.
- Create NewsStorageService to coordinate news data management.
2026-04-30 12:10:00 +08:00

78 lines
2.3 KiB
JavaScript

const express = require('express')
/**
* NewsApiCompatibilityController
*
* Mimics the subset of NewsAPI endpoints currently consumed by the front-end.
*/
class NewsApiCompatibilityController {
constructor(storageService) {
this._storageService = storageService
this.router = express.Router()
this._registerRoutes()
}
/**
* @returns {void}
*/
_registerRoutes() {
this.router.get('/everything', this._wrap(async (request, response) => {
const categoryKey = this._normalizeCategoryKey(request.query.q)
const page = this._parsePositiveInteger(request.query.page, 1)
const pageSize = this._parsePositiveInteger(request.query.pageSize, 10)
const document = await this._storageService.getCategoryNewsPage(categoryKey, page, pageSize)
response.json({
status: 'ok',
totalResults: document.total,
articles: document.articles
})
}))
this.router.get('/top-headlines', this._wrap(async (request, response) => {
const categoryKey = this._normalizeCategoryKey(request.query.category || 'business')
const page = this._parsePositiveInteger(request.query.page, 1)
const pageSize = this._parsePositiveInteger(request.query.pageSize, 10)
const document = await this._storageService.getCategoryNewsPage(categoryKey, page, pageSize)
response.json({
status: 'ok',
totalResults: document.total,
articles: document.articles
})
}))
}
/**
* @param {unknown} value
* @returns {string}
*/
_normalizeCategoryKey(value) {
const categoryKey = String(value || 'finance').trim().toLowerCase()
return categoryKey
}
/**
* @param {unknown} value
* @param {number} fallback
* @returns {number}
*/
_parsePositiveInteger(value, fallback) {
const parsed = Number(value)
return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback
}
/**
* @param {(request: import('express').Request, response: import('express').Response) => Promise<void>} handler
* @returns {(request: import('express').Request, response: import('express').Response, next: import('express').NextFunction) => void}
*/
_wrap(handler) {
return (request, response, next) => {
handler(request, response).catch(next)
}
}
}
module.exports = {
NewsApiCompatibilityController
}