117 lines
3.0 KiB
TypeScript
117 lines
3.0 KiB
TypeScript
import fastify, {
|
|
FastifyInstance,
|
|
FastifyListenOptions,
|
|
FastifyReply,
|
|
FastifyRequest
|
|
} from 'fastify'
|
|
import { PinoLoggerOptions } from 'fastify/types/logger'
|
|
import { Proxy } from './proxy'
|
|
import { Logger } from 'pino'
|
|
import 'dotenv/config'
|
|
|
|
const host = process.env.HOST
|
|
const port = parseInt(process.env.PORT ?? '8080', 10)
|
|
const baseUrl = process.env.NITTER_BASE_URL
|
|
const concurrency = parseInt(process.env.CONCURRENCY ?? '1', 10)
|
|
const retryAfterMillis = process.env.RETRY_AFTER_MILLIS
|
|
? parseInt(process.env.RETRY_AFTER_MILLIS, 10)
|
|
: null
|
|
const maxCacheSize = parseInt(process.env.MAX_CACHE_SIZE ?? '100000', 10)
|
|
const logLevel = process.env.LOG_LEVEL ?? 'debug'
|
|
|
|
const server = fastify({
|
|
logger: {
|
|
name: 'app',
|
|
level: logLevel,
|
|
...(logLevel == 'trace' ? { transport: { target: 'pino-pretty' } } : {})
|
|
} as PinoLoggerOptions
|
|
})
|
|
|
|
const log = server.log as Logger
|
|
const proxy = new Proxy(
|
|
log,
|
|
baseUrl,
|
|
concurrency,
|
|
retryAfterMillis,
|
|
maxCacheSize
|
|
)
|
|
|
|
async function main() {
|
|
server.register(
|
|
(fastify: FastifyInstance, opts, done) => {
|
|
fastify.get(
|
|
`/user/:username`,
|
|
{},
|
|
async (request: FastifyRequest, reply: FastifyReply) => {
|
|
log.debug(
|
|
{
|
|
headers: request.headers,
|
|
reqId: request.id,
|
|
params: request.params
|
|
},
|
|
'incoming request /user/:username'
|
|
)
|
|
const { username } = request.params as any
|
|
const { status, data } = await proxy.getUser(username, {
|
|
reqId: request.id
|
|
})
|
|
reply.status(status).send(data)
|
|
}
|
|
)
|
|
|
|
fastify.get(
|
|
`/user/:userId/tweets`,
|
|
{},
|
|
async (request: FastifyRequest, reply: FastifyReply) => {
|
|
const { userId } = request.params as any
|
|
const { cursor } = request.query as any
|
|
const { status, data } = await proxy.getUserTweets(userId, cursor, {
|
|
reqId: request.id
|
|
})
|
|
reply.status(status).send(data)
|
|
}
|
|
)
|
|
|
|
fastify.get(
|
|
`/tweet/:id`,
|
|
{},
|
|
async (request: FastifyRequest, reply: FastifyReply) => {
|
|
const { id } = request.params as any
|
|
const { status, data } = await proxy.getTweetById(id, {
|
|
reqId: request.id
|
|
})
|
|
reply.status(status).send(data)
|
|
}
|
|
)
|
|
|
|
done()
|
|
},
|
|
{ prefix: '/api' }
|
|
)
|
|
|
|
server.setNotFoundHandler((request: FastifyRequest, reply: FastifyReply) => {
|
|
reply.status(404).send({ message: `Method not found` })
|
|
})
|
|
|
|
server.setErrorHandler(
|
|
(err: Error, request: FastifyRequest, reply: FastifyReply) => {
|
|
const { log } = request
|
|
log.error(err)
|
|
// Send error response
|
|
reply.status(500).send({ message: `Internal server error` })
|
|
}
|
|
)
|
|
|
|
// await server.register(import('@fastify/rate-limit'), {
|
|
// max: 100,
|
|
// timeWindow: '1 minute'
|
|
// })
|
|
|
|
await server.listen({ port, host } as FastifyListenOptions)
|
|
}
|
|
|
|
main().catch((err) => {
|
|
log.fatal(err)
|
|
process.exit(1)
|
|
})
|