89 lines
No EOL
2.4 KiB
TypeScript
89 lines
No EOL
2.4 KiB
TypeScript
import fastify from 'fastify';
|
|
import { Type, Static } from '@sinclair/typebox';
|
|
import { TypeBoxValidatorCompiler } from '@fastify/type-provider-typebox';
|
|
|
|
// Create Fastify instance
|
|
const app = fastify({ logger: true });
|
|
|
|
// Set up TypeBox validator
|
|
app.setValidatorCompiler(TypeBoxValidatorCompiler);
|
|
|
|
// Define TypeBox schema as the single source of truth
|
|
const UserSchema = Type.Object({
|
|
id: Type.Number(),
|
|
name: Type.String(),
|
|
email: Type.String(),
|
|
age: Type.Number({ minimum: 0 })
|
|
});
|
|
|
|
// Derive TypeScript type from the TypeBox schema
|
|
type User = Static<typeof UserSchema>;
|
|
|
|
// Response schema for better documentation
|
|
const ResponseSchema = Type.Object({
|
|
user: UserSchema,
|
|
canDrink: Type.Boolean(),
|
|
greeting: Type.String()
|
|
});
|
|
|
|
// Main function to set up the server
|
|
async function startServer() {
|
|
// Register Swagger plugin using dynamic import
|
|
await app.register(import('@fastify/swagger'), {
|
|
swagger: {
|
|
info: {
|
|
title: 'User API',
|
|
description: 'API for user operations with TypeBox validation',
|
|
version: '1.0.0'
|
|
},
|
|
tags: [
|
|
{ name: 'users', description: 'User related endpoints' }
|
|
]
|
|
}
|
|
});
|
|
|
|
// Register Swagger UI plugin using dynamic import
|
|
await app.register(import('@fastify/swagger-ui'), {
|
|
routePrefix: '/swagger',
|
|
uiConfig: {
|
|
docExpansion: 'list',
|
|
deepLinking: false
|
|
},
|
|
staticCSP: true
|
|
});
|
|
|
|
// Register our route
|
|
app.post('/api/users', {
|
|
schema: {
|
|
description: 'Create a new user',
|
|
tags: ['users'],
|
|
body: UserSchema,
|
|
response: {
|
|
200: ResponseSchema
|
|
}
|
|
}
|
|
}, async (request, reply) => {
|
|
const user = request.body as User;
|
|
|
|
const canDrink = user.age >= 21;
|
|
const greeting = `Hello ${user.name.toUpperCase()}, your email ${user.email.toLowerCase()} has been recorded`;
|
|
|
|
return { user, canDrink, greeting };
|
|
});
|
|
|
|
// Wait until all plugins are ready
|
|
await app.ready();
|
|
|
|
// Start the server
|
|
try {
|
|
await app.listen({ port: 3000 });
|
|
console.log('Server running at http://localhost:3000');
|
|
console.log('Swagger UI available at: http://localhost:3000/swagger');
|
|
} catch (err) {
|
|
app.log.error(err);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Start the server
|
|
startServer(); |