'how to create a path and query validation in adonis5
In adonis5 i am currently using schema based validation, but these validation is only applicable to request body . how i can validate path and query parameter validation
import { rules, schema } from '@ioc:Adonis/Core/Validator'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
class UserValidator {
async createUser(ctx: HttpContextContract) {
const createUserSchema = schema.create({
firstName: schema.string({
escape: true,
trim: true,
}, [
rules.minLength(3),
]),
lastName: schema.string({
escape: true,
trim: true
}, [
rules.minLength(3)
]),
email: schema.string({}, [
rules.email({
sanitize: true,
ignoreMaxLength: true,
domainSpecificValidation: true,
}),
rules.unique({
table: 'users',
column: 'email'
})
]),
password: schema.string({}, [
rules.minLength(8)
])
})
await ctx.request.validate({
schema: createUserSchema,
messages: {
'required': '{{field}} is required to create an account.',
'minLength': '{{field}} must be atleast {{options.minLength}} characters',
'unique': '{{field}} should be {{rule}}',
}
})
}
Solution 1:[1]
You can add params object under schema.create({}) function.
public schema = schema.create({
params: schema.object().members({
id: schema.string({escape: true, trim: true}, [
rules.uuid({version: 4})
])
})
});
Reference: https://docs.adonisjs.com/guides/validator/introduction#validating-http-requests
Solution 2:[2]
You're almost there, you just need to explicitly pass the request parameters or query parameters in the data object for the validate method, like so:
await ctx.request.validate({
schema: createUserSchema,
data: {
id: ctx.request.params.id // <<< path/query params can be provided here
},
messages: {
'required': '{{field}} is required to create an account.',
'minLength': '{{field}} must be atleast {{options.minLength}} characters',
'unique': '{{field}} should be {{rule}}',
}
})
Remember to name your data
properties the same way you provided in the schema. So in the example above, id
should be a property in the schema as well.
Solution 3:[3]
You can also use both combining body & params. Here is what I did on a similar case.
import omit from 'lodash/omit';
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
import { schema, validator, rules } from '@ioc:Adonis/Core/Validator';
export default class HeroesController {
public async patch({ params, request }: HttpContextContract) {
const patchHeroSchema = schema.create({
// heroId doesn't exist in request but is in route (/heroes/:heroId)
heroId: schema.number([rules.exists({ table: 'heroes', column: 'id' })]),
name: schema.string.optional(),
avatar: schema.string.optional(),
description: schema.string.optional(),
profession: schema.string.optional(),
});
const hero = await request.validate({
schema: patchHeroSchema,
messages: {
exists: "Hero doesn't exist",
},
data: {
// Here we add the route params & request body
heroId: params.heroId,
...request.body(),
},
reporter: validator.reporters.jsonapi,
});
// Here we are sure that hero.heroId exists in db
const heroToUpdate = await Hero.find(hero.heroId);
// We still need to omit heroId as it's not part of the object we want to merge
const finalHero = omit(hero, 'heroId');
const heroUpdated = await heroToUpdate?.merge(finalHero).save();
return heroUpdated;
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Tristan Rosales |
Solution 2 | stamblew |
Solution 3 | Kai23 |