13

Using Joi schema validation, is it possible to validate against MongoDB ObjectID's?

Something like this could be great:

_id: Joi.ObjectId().required().error(errorParser),
Raz Buchnik
  • 7,753
  • 14
  • 53
  • 96

8 Answers8

17
const Joi = require('@hapi/joi')
Joi.objectId = require('joi-objectid')(Joi)
 
const schema = Joi.object({
  id: Joi.objectId(),
  name: Joi.string().max(100),
  date: Joi.date()
})

checkout https://www.npmjs.com/package/joi-objectid

Akarsh Satija
  • 1,756
  • 2
  • 22
  • 28
prince Arthur
  • 221
  • 3
  • 5
16

I find that if I do

Joi.object({
  id: Joi.string().hex().length(24)
})

it works without installing any external library or using RegEx

The hex makes sure the string contains only hexadecimal characters and the length makes sure that it is a string of exactly 24 characters

orimdominic
  • 995
  • 10
  • 23
4

This package works if you are using the new version of Joi.

const Joi = require('joi-oid')

const schema = Joi.object({
  id: Joi.objectId(),
  name: Joi.string(),
  age: Joi.number().min(18),
})

package: https://www.npmjs.com/package/joi-oid

3

If you want a TypeScript version of the above library integrated with Express without installing anything:

import Joi from '@hapi/joi';
import { createValidator } from 'express-joi-validation';

export const JoiObjectId = (message = 'valid id') => Joi.string().regex(/^[0-9a-fA-F]{24}$/, message)

const validator = createValidator({
    passError: true,
});

const params = Joi.object({
    id: JoiObjectId().required(),
});

router.get<{ id: string }>(
    '/:id',
    validator.params(params),
    (req, res, next) => { 
       const { id } = req.params; // id has string type
       .... 
    }
);
  • 1
    This should be the accepted answer. A simple RegEx pattern instead of a whole additional library. – GusSL Feb 12 '22 at 02:20
0

I share mine

let id =
  Joi.string()
    .regex(/^[0-9a-fA-F]{24}$/)
    .message('must be an oid')
arcollector
  • 101
  • 5
0

With joi naked package you can use this:

const ObjectId = joi.object({
   id: joi.binary().length(12),
})
Radu Diță
  • 13,476
  • 2
  • 30
  • 34
0

This is a core function without any external package. I have used Joi and mongoose packages to achieve it.

const Joi = require("joi");
const ObjectID = require("mongodb").ObjectID;

const schema = Joi.object({
    id: Joi.string().custom((value, helpers) => {
            const filtered = ObjectID.isValid(value)
            return !filtered ? helpers.error("any.invalid") : value;
        },
        "invalid objectId", ).required(),
    name: Joi.string(),
    age: Joi.number().min(18),
})
0

I see many correct answers here, but I also want to express my opinion. I am not against installing npm packages, but installing one package just to validate an object id is overkill. I know programmers are lazy but C'mooon :)

Here is my full code function that validates two object id properties, very simple:

function validateRental(rental) {
  const schema = Joi.object({
    movieId: Joi.string()
      .required()
      .regex(/^[0-9a-fA-F]{24}$/, 'object Id'),
    customerId: Joi.string()
      .required()
      .regex(/^[0-9a-fA-F]{24}$/, 'object Id'),
  })

  const { error } = schema.validate(rental)

  return {
    valid: error == null,
    message: error ? error.details[0].message : null,
  }
}

This way, if any of the properties contain invalid id like this:

{
    "movieId": "123456",
    "customerId": "63edf556f383d108d54a68a0"
}

This will be the error message:

`"movieId" with value "123456" fails to match the object Id pattern`