簡體   English   中英

如何使用Joi,Mongoose和Hapi驗證鑒別器數組?

[英]How to validate a discriminator array using Joi, Mongoose & Hapi?

假設我們建立了這樣一個模型:

const model = new mongoose.Schema({
  foo: {
    type: String,
    required: true,
  },
  discriminatorArray: [new mongoose.Schema({
    bar: {
      type: String,
      required: false,
    }
  }, {
    discriminatorKey: 'baz',
    _id: false,
  })],
});

const docArray = model.path('discriminatorArray');

docArray.discriminator('discriminatorValue1', anotherModel1);
docArray.discriminator('discriminatorValue2', anotherModel2);

mongoose.model('Model', model);

結果是:

{
  "foo": "someValue",
  "discriminatorArray": [{
    "bar": "someValue",
    "baz": "discriminatorValue1",
    "anotherModel1Prop": "someValue"
  }, {
    "bar": "someValue",
    "baz": "discriminatorValue2",
    "anotherModel2Prop": "someValue"
  }]
}

您如何使用Joi正確驗證陣列?

樣板:

Joi.validate(payload, Joi.object({
  foo: Joi
    .string()
    .required(),
  discriminatorArray: Joi
    .array()
    .items(Joi.object({
      bar: Joi
        .string()
        .optional(),
      baz: Joi
        .string()
        .valid(['discriminatorValue1', 'discriminatorValue2'])
        .required(),
    }))
    .required(),
}));

我可以執行此操作的唯一2種方法是:

  1. 包括anotherModel1和anotherModel2的所有可能的鍵,然后使用
Joi.when('baz', {
  is: 'discriminatorValue1',
  then: Joi.string(),
  otherwise: Joi.forbidden(),
})

但是,不同的模型共享一些相同的密鑰,這最終會很混亂,包括所有密鑰對我來說是沒有意義的,而是為不同的標識符創建一個單獨的架構,並使用類似以下內容的方法:

const items = Joi.object().keys({
  bar: Joi
    .string()
    .optional(),
  baz: Joi
    .string()
    .valid(['discriminatorValue1', 'discriminatorValue2'])
    .required(),
});

const schema = Joi.object({
  foo: Joi
    .string()
    .required(),
  discriminatorArray: Joi
    .array()
    .items(items.when('baz', {
      is: 'discriminatorValue1',
      then: object.keys(anotherSchema1),
    }).when('baz', {
      is: 'discriminatorValue2',
      then: object.keys(anotherSchema2),
    })),
});
  1. 將模型更改為如下所示:
{
  "foo": "someValue",
  "someArray": [{
    "baz": "discriminatorValue1",
    "discriminatorArray": [{
      "anotherModel1Prop": "someValue"
    }]
  }, {
    "baz": "discriminatorValue2",
    "discriminatorArray": [{
      "anotherModel2Prop": "someValue"
    }]
  }]
}

這樣Joi驗證將如下所示(未經測試):

Joi.validate(payload, Joi.object({
  foo: Joi
    .string()
    .required(),
  someArray: Joi
    .array()
    .items(Joi.object({
      baz: Joi
        .string()
        .valid(['discriminatorValue1', 'discriminatorValue2'])
        .required(),
      discriminatorArray: Joi
        .array()
        .when('baz', {
          is: 'discriminatorValue1',
          then: Joi
            .array()
            .items(Joi.object({
              anotherModel1Prop: Joi
                .string()
                .required(),
            })),
        })
        .when('baz', {
          is: 'discriminatorValue2',
          then: Joi
            .array()
            .items(Joi.object({
              anotherModel2Prop: Joi
                .string()
                .required(),
            })),
        }),
    }))
    .required(),
}));

任何想法和解決方案都將很棒。

資源:

我決定包括所有可能的鍵並編寫一些邏輯以基於配置文件構建架構。

配置數組如下所示:

{
  key: 'anotherModel1Key',
  required: true,
}

然后我寫了這樣的東西:

const items = {
  bar: Joi
    .string()
    .optional(),
  baz: Joi
    .string()
    .valid(['discriminatorValue1', 'discriminatorValue2'])
    .required(),
};

// function to add additional keys from configs which ends with

items[key] = Joi.when('baz', {
  is: Joi.only(arrayOfBazValuesIdentifyingWhenThisKeyIsAllowed),
  then: Joi.string().trim()[required](),
  otherwise: Joi.forbidden(),
});

隨后返回架構:

return Joi.validate(payload, Joi.object({
  foo: Joi
    .string()
    .required(),
  discriminatorArray: Joi
    .array()
    .items(items)
    .required(),
}));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM