| |
| |
| |
| |
| |
| |
| import express, { Request, Response } from 'express' |
|
|
| import FailBot from '@/observability/lib/failbot' |
| import { searchCacheControl } from '@/frame/middleware/cache-control' |
| import catchMiddlewareError from '@/observability/middleware/catch-middleware-error' |
| import { setFastlySurrogateKey, SURROGATE_ENUMS } from '@/frame/middleware/set-fastly-surrogate-key' |
| import { getAISearchAutocompleteResults } from '@/search/lib/get-elasticsearch-results/ai-search-autocomplete' |
| import { getSearchFromRequestParams } from '@/search/lib/search-request-params/get-search-from-request-params' |
| import { getGeneralSearchResults } from '@/search/lib/get-elasticsearch-results/general-search' |
| import { combinedSearchRoute } from '@/search/lib/routes/combined-search-route' |
| import { handleExternalSearchAnalytics } from '@/search/lib/helpers/external-search-analytics' |
|
|
| const router = express.Router() |
|
|
| router.get('/legacy', (req: Request, res: Response) => { |
| res.status(410).send('Use /api/search/v1 instead.') |
| }) |
|
|
| router.get( |
| '/v1', |
| catchMiddlewareError(async (req: Request, res: Response) => { |
| const { indexName, searchParams, validationErrors } = getSearchFromRequestParams( |
| req, |
| 'generalSearch', |
| ) |
| if (validationErrors.length) { |
| |
| return res.status(400).json(validationErrors[0]) |
| } |
|
|
| |
| const analyticsError = await handleExternalSearchAnalytics(req, 'general-search') |
| if (analyticsError) { |
| return res.status(analyticsError.status).json({ |
| error: analyticsError.error, |
| }) |
| } |
|
|
| const getResultOptions = { |
| indexName, |
| searchParams, |
| } |
| try { |
| const { meta, hits, aggregations } = await getGeneralSearchResults(getResultOptions) |
|
|
| if (process.env.NODE_ENV !== 'development') { |
| searchCacheControl(res) |
| |
| |
| |
| setFastlySurrogateKey(res, SURROGATE_ENUMS.MANUAL) |
| } |
|
|
| res.status(200).json({ meta, hits, aggregations }) |
| } catch (error) { |
| await handleGetSearchResultsError(req, res, error, getResultOptions) |
| } |
| }), |
| ) |
|
|
| router.get( |
| '/ai-search-autocomplete/v1', |
| catchMiddlewareError(async (req: Request, res: Response) => { |
| |
| |
| |
| const force = {} as any |
| if (!req.query.query) { |
| force.query = '' |
| } |
| const { |
| indexName, |
| validationErrors, |
| searchParams: { query, size, debug }, |
| } = getSearchFromRequestParams(req, 'aiSearchAutocomplete', force) |
| if (validationErrors.length) { |
| return res.status(400).json(validationErrors[0]) |
| } |
|
|
| const getResultOptions = { |
| indexName, |
| query, |
| size, |
| debug, |
| } |
| try { |
| const { meta, hits } = await getAISearchAutocompleteResults(getResultOptions) |
|
|
| if (process.env.NODE_ENV !== 'development') { |
| searchCacheControl(res) |
| setFastlySurrogateKey(res, SURROGATE_ENUMS.DEFAULT) |
| } |
|
|
| res.status(200).json({ meta, hits }) |
| } catch (error) { |
| await handleGetSearchResultsError(req, res, error, getResultOptions) |
| } |
| }), |
| ) |
|
|
| |
| |
| router.get( |
| '/combined-search/v1', |
| catchMiddlewareError(async (req: Request, res: Response) => { |
| combinedSearchRoute(req, res) |
| }), |
| ) |
|
|
| export async function handleGetSearchResultsError( |
| req: Request, |
| res: Response, |
| error: any, |
| options: any, |
| ) { |
| if (process.env.NODE_ENV === 'development') { |
| console.error(`Error calling getSearchResults(${options})`, error) |
| } else { |
| const reports = FailBot.report(error, { url: req.url, ...options }) |
| if (reports) await Promise.all(reports) |
| } |
| res.status(500).json({ error: error.message }) |
| } |
|
|
| |
| router.get('/', (req: Request, res: Response) => { |
| res.redirect(307, req.originalUrl.replace('/search', '/search/v1')) |
| }) |
|
|
| router.get('/ai-search-autocomplete', (req: Request, res: Response) => { |
| res.redirect( |
| 307, |
| req.originalUrl.replace('/search/ai-search-autocomplete', '/search/ai-search-autocomplete/v1'), |
| ) |
| }) |
|
|
| router.get('/combined-search', (req: Request, res: Response) => { |
| res.redirect( |
| 307, |
| req.originalUrl.replace('/search/combined-search', '/search/combined-search/v1'), |
| ) |
| }) |
|
|
| export default router |
|
|