A fastify Papr plugin integration.
pnpm add @inaiat/fastify-papr @fastify/mongodb
Next, set up the plugin:
import fastifyMongodb from '@fastify/mongodb'
import fastifyPaprPlugin, { asCollection, FastifyPaprOptions } from ' @inaiat/fastify-papr'
import fp from 'fastify-plugin'
import { Model, schema, types } from 'papr'
const userSchema = schema({
name: types.string({ required: true, minLength: 10, maxLength: 100 }),
phone: types.string({ required: true, minLength: 8, maxLength: 20 }),
})
const userIndexes = [{ key: { name: 1 } }]
declare module '@inaiat/fastify-papr' {
interface FastifyPapr {
user: Model<typeof userSchema[0], Partial<typeof userSchema[1]>>
}
}
export default fp<FastifyPaprOptions>(
async (fastify) => {
await fastify.register(fastifyMongodb, {
url: 'mongodb://localhost:27017',
})
await fastify.register(fastifyPaprPlugin, {
db: fastify.mongo.client.db('test'),
models: {
user: asCollection('user', userSchema, userIndexes)
},
})
},
{ name: 'papr' },
)
How to use:
import { FastifyPluginAsync } from 'fastify'
import { Static, Type } from '@sinclair/typebox'
import { MongoServerError } from 'mongodb'
import { MongoValidationError, isMongoServerError } from '@inaiat/fastify-papr'
const userDto = Type.Object({
name: Type.String({ maxLength: 100, minLength: 10 }),
phone: Type.String({ maxLength: 20, minLength: 8 }),
})
const userRoute: FastifyPluginAsync = async (fastify) => {
fastify.post<{ readonly Body: Static<typeof userDto> }>(
'/user',
{
schema: {
body: userDto,
},
},
async (req, reply) => {
try {
const result = await fastify.papr.user.insertOne(req.body)
return result
} catch (error) {
// Check if it's a MongoDB validation error
if (isMongoServerError(error) && error.code === 121) {
const validationError = new MongoValidationError(error)
// Log or process the validation details
console.error('Validation failed:', validationError.getValidationErrorsAsString())
// Example: Get errors for a specific field
const nameErrors = validationError.getFieldErrors('name')
if (nameErrors) {
console.error('Name field errors:', nameErrors)
}
// Return a 400 Bad Request with validation details
return reply.status(400).send({
message: 'Validation failed',
errors: validationError.validationErrors,
})
}
// Handle other errors
fastify.log.error(error)
return reply.status(500).send({ message: 'Internal Server Error' })
}
},
)
}
export default userRoute
We've consolidated and improved the MongoDB validation error handling in v2.0.0:
- The
SimpleDocFailedValidationError
and related types have been replaced with a newMongoValidationError
class - The error extraction logic has been improved for better type safety and reliability
- New helper methods have been added for easier access to validation errors
Replace imports:
- import { SimpleDocFailedValidationError, tryExtractSimpleDocFailedValidation } from '@inaiat/fastify-papr'
+ import { MongoValidationError, extractValidationErrors } from '@inaiat/fastify-papr'
Use the new class and methods:
- const simpleError = new SimpleDocFailedValidationError(error)
- const hasErrors = simpleError.documentFailedValidation
- const errorDetails = simpleError.schemaRulesNotSatisfied
- const errorJson = simpleError.schemaRulesNotSatisfiedAsString()
+ const validationError = new MongoValidationError(error)
+ const hasErrors = validationError.hasValidationFailures
+ const errorDetails = validationError.validationErrors
+ const errorJson = validationError.getValidationErrorsAsString()
New features:
// Get validation errors for a specific field
const nameErrors = validationError.getFieldErrors('name')
Type changes:
- DocumentFailedValidation → DocumentValidationError
- PropertiesNotSatisfied → ValidationProperty
- PropertyDetail → ValidationDetail
- SimpleDocFailedValidation → ValidationErrors
To learn more about the code and see additional examples, you can visit the Papr documentation at plexinc.github.io/papr and explore test folder on this project.