'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