Search code examples
node.jsvalidationhapi.jsjoi

hapi 17 with joi validation AssertionError


I'm porting an existing Hapi 16 app to Hapi 17 - and have run into problems with Joi validation...

<!-- language: lang-js -->

    'use strict';

const Joi = require('joi');

const validator = Joi.object({
        "sku": Joi.string().required(),
        "name": Joi.string()
      // cut for berevity..
        )
  })

module.exports = {
  method: ["POST", "PUT"],
  path: "/api/products",
  options: {
    validate: {
      params: validator
    },
    async handler(request, h) {
      try {
        const updateOrCreateItemQuery = { sku: request.payload.sku };        
        const result = await request.postItem( "product", updateOrCreateItemQuery);
        return result;
      } catch (err) {
        throw h.internal("Internal MongoDB error", err);
      }
    }
  }
};

When I start the app (not when I visit the route) I get the following error: { AssertionError [ERR_ASSERTION]: Cannot set path parameters validations without path parameters: POST /api/products

I've stripped everything back - so its just this route. Its deffinately something to do with Joi, as when I remove the validation - it works... I've read the docs - and cant see what I'm doing wrong...

( I have applied various decorators to the request object - eg postItem etc, which... posts an item to the DB)


Solution

  • <!-- language: lang-js -->
    
        'use strict';
    
    const Joi = require('joi');
    
    const validator = {
            "sku": Joi.string().required(),
            "name": Joi.string()
          // cut for berevity..
            )
      }
    
    module.exports = {
      method: ["POST", "PUT"],
      path: "/api/products",
      options: {
        validate: {
          payload: validator
        },
        async handler(request, h) {
          try {
            const updateOrCreateItemQuery = { sku: request.payload.sku };        
            const result = await request.postItem( "product", updateOrCreateItemQuery);
            return result;
          } catch (err) {
            throw h.internal("Internal MongoDB error", err);
          }
        }
      }
    };
    

    Turned validate into a regular object, and set the validate option to payload.... which makes sense, as this is a this route accepts POST and PUT.