Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
26.95k stars 3.84k forks source link

Any plan to use $jsonSchema? #11162

Open shahidcodes opened 2 years ago

shahidcodes commented 2 years ago

Is there any plan use $jsonSchema for schema validation since MongoDB now supports it out of the box?

vkarpov15 commented 2 years ago

We're not likely to make this change any time in the next few years. Since $jsonSchema is stored on the MongoDB server but Mongoose schemas are stored on the application, switching Mongoose to using $jsonSchema would be a massive change that would likely break a lot of codebases.

veeramarni commented 2 years ago

@vkarpov15 Can we use mix of both? Lets say i have a field with type Mixed and want to use JSON Schema fro that specific filed only.

vkarpov15 commented 2 years ago

It is possible, we'll reopen this and consider it for a future release.

Uzlopak commented 2 years ago

Atleast it should be possible to pass the jsonschema to the mongoose schema or create the jsonschema from the mongoose schema .

veeramarni commented 2 years ago

Any example how to pass jsonschema to the mongoose schema?

Uzlopak commented 2 years ago

I checked a month ago. There is currently no opportunity to pass the jsonschema from the mongoose schema to createCollection

javierguzman commented 2 years ago

I am also interested on this feature

GO-DIE commented 2 years ago

Look forward to seeing this feature supported

GiovanniCardamone commented 1 year ago

Also interested in this feature

webarthur commented 1 year ago

A possible workaround:

Install mongoose-schema-jsonschema module:

npm i mongoose-schema-jsonschema

Create json schema from mongoose schema:

const mongoose = require('mongoose')
require('mongoose-schema-jsonschema')(mongoose)

const { Schema } = mongoose

const schema = new Schema({

  name: {
    type: String,
    required: [true, 'Please, fill your name.'],
    minlength: 2,
    maxlength: 120,
  },

  password: {
    type: String,
    required: [true, 'Please, fill your password.'],
    minlength: 8,
    maxlength: 40,
  },

  age: Number,

  active: {
    type: Boolean,
    // default: true, // issue here
  },

  hobbies: [String],

}, { timestamps: { createdAt: false, updatedAt: false } })

const jsonSchema = schema.jsonSchema()

schema.on('init', () => {
  const db = mongoose.connection

  db.once('open', () => {
    db.db.command({
      collMod: 'users',
      validator: {
        $jsonSchema: jsonSchema
      },
      validationLevel: 'moderate',
      validationAction: 'error'
    })
    .then(() => {
      console.log('Validation has been set up successfully')
    })
    .catch((error) => {
      console.error('Error configuring schema validation:', error)
    })
  })
})

const User = mongoose.model('user', schema)

module.exports = User

The json schema generated:

{
    "name": {
      "type": "string",
      "minLength": 2,
      "maxLength": 120
    },
    "password": {
      "type": "string",
      "minLength": 8,
      "maxLength": 40
    },
    "age": {
      "type": "number"
    },
    "active": {
      "type": "boolean"
    },
    "hobbies": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "_id": {
      "type": "string",
      "pattern": "^[0-9a-fA-F]{24}$"
    }
  },
  "required": [ "name", "password" ]
}

But there are some issues here. According to the MongoDB documentation, it is not possible to use some properties, such as default and format. How could this be resolved?

harisvsulaiman commented 1 year ago

@vkarpov15 can we revisit this

vkarpov15 commented 1 year ago

@harisvsulaiman what are you suggesting? Do you want Mongoose to automatically apply JSON schema on MongoDB server based on Mongoose schema? Would a plugin be sufficient?

harisvsulaiman commented 1 year ago

@harisvsulaiman what are you suggesting? Do you want Mongoose to automatically apply JSON schema on MongoDB server based on Mongoose schema? Would a plugin be sufficient?

@vkarpov15 yes a schema generated from mongoose schema which is applied on boot .

I think a plugin is the best way to go about it. It's easier for people to optin.

harisvsulaiman commented 1 year ago

@vkarpov15 we could create a plugin with above mentioned package and strip out the unsupported fields

harisvsulaiman commented 1 year ago

@vkarpov15 https://github.com/plexinc/papr seems to use the jsonschema spec