簡體   English   中英

Joi 驗證器條件模式

[英]Joi validator conditional schema

我需要創建動態模式以根據請求查詢中的鍵使用Joi 驗證器node js驗證我的 api 請求查詢。 說下面提到的模式是我的有效查詢。

我正在使用hapi/joi 16.1.8版本16.1.8

組合1

{ type: 1, firstname: 'user first name', lastname: 'user last name'}

組合2

{ type: 2 , salary: 1000, pension: 200}

組合3

{ type: 3 , credit: 550, debit: 100}

如您所見,對象鍵因type的值而異。 如何正確處理?

我們可以使用Joi.alternatives處理兩個條件,例如

const schema = Joi.alternatives().conditional(Joi.object({ type: 1 }).unknown(), {
    then: Joi.object({
        type: Joi.string(),
        firstname: Joi.string(),
        lastname: Joi.string()
    }),
    otherwise: Joi.object({
        type: Joi.number(),
        salary: Joi.any(),
        pension: Joi.any()
    })
});

但是如何在 3 個條件下做到這一點?

我以稍微不同的方式實現了相同的目標。 在這里發布相同的內容,因為這可能對將來的某人有用。

const schema = Joi.object({
    type: Joi.number().required().valid(1, 2, 3),
    firstname: Joi.alternatives().conditional('type', { is: 1, then: Joi.string().required() }),
    lastname: Joi.alternatives().conditional('type', { is: 1, then: Joi.string().required() }),
    salary: Joi.alternatives().conditional('type', { is: 2, then: Joi.number().required() }),
    pension: Joi.alternatives().conditional('type', { is: 2, then: Joi.number().required() }),
    credit: Joi.alternatives().conditional('type', { is: 3, then: Joi.number().required() }),
    debit: Joi.alternatives().conditional('type', { is: 3, then: Joi.number().required() }),
}))

這正如預期的那樣完美地工作。

當類型值為1 ,對象應該只有typefirstnamelastname

當類型值為2 ,對象應該只有typesalarypension

當 type 值為3 ,對象應該只有typecreditdebit

任何其他組合都將從 joi 驗證器中間件層作為錯誤拋出。 此外,除 1、2 和 3 之外的任何其他類型值都將引發錯誤。

這個對我有用!

var Joi = require('joi');

var schema = {
    a: Joi.any().when('b', { is: 5, then: Joi.required(), otherwise: Joi.optional() }),
    b: Joi.any()
};

var thing = {
    b: 5
};
var validate = Joi.validate(thing, schema);

// returns
{
    error: null,
    value: {
        b: 5
    }
}

這是 參考

文檔中,看起來switch是與alternatives.conditional一起使用的有效鍵。 您可以嘗試以下方法嗎?

const schema = Joi.alternatives().conditional(Joi.object({
  type: 1
}).unknown(), {
  switch: [{
    is: 1,

    then: Joi.object({
      type: Joi.string(),
      firstname: Joi.string(),
      lastname: Joi.string(),
    }),
  }, {
    is: 2,

    then: Joi.object({
      type: Joi.number(),
      salary: Joi.any(),
      pension: Joi.any(),
    }),
  }, {
    // ...
  }],
});

編輯

在任何地方都找不到有關使用switch關鍵字的任何示例...

但是在hapijs/joi github 中找到了一些其他方法來實現它

const schema = Joi.object({
     a: Joi.number().required(),
     b: Joi.alternatives()
             .conditional('a', [
                 { is: 0, then: Joi.valid(1) },
                 { is: 1, then: Joi.valid(2) },
                 { is: 2, then: Joi.valid(3), otherwise: Joi.valid(4) }
    ])
});

我試圖找到一種方法來做類似的事情。 然后我就想通了。

const Joi = require('joi');
const schema = Joi.object({
  type: Joi.number().valid(1,2,3),
  // anything common
}).when(Joi.object({type: Joi.number().valid(1)}).unknown(), {
  then: Joi.object({
    firstname: Joi.string(),
    lastname: Joi.string(),
  })
})
.when(Joi.object({type: Joi.number().valid(2)}).unknown(), {
  then: Joi.object({
    salary: Joi.number(),
    pension: Joi.number(),
  })
})
.when(Joi.object({type: Joi.number().valid(3)}).unknown(), {
  then: Joi.object({
    credit: Joi.number(),
    debit: Joi.number(),
  })
});

我想做同樣的事情,但條件應該取決於請求方法而不是查詢參數。 我最終得到了下一個解決方案:

const schema = Joi.when(Joi.ref("$requestMethod"), {
  switch: [
    {
      is: "POST",
      then: Joi.object({
        name: Joi.string().trim().max(150).required(),
        description: Joi.string().max(255),
        active: Joi.boolean().required(),
        }),
      }),
    },
    {
      is: "PUT",
      then: Joi.object({
        name: Joi.string().trim().max(150).required(),
        description: Joi.string().max(255),            
      }),
    },
  ],
});


schema.validate(req.body, { context: { requestMethod: req.method } });

Joi when() 條件文檔https://joi.dev/api/?v=17.4.1#anywhencondition-options

使用條件/開關,其語法也更具可讀性。

以下 Joi 摘錄將在$.type === Type.REFERENCE時強制$.referenceClass的存在。 當它這樣做時,它將確保值是接受的值 - ...classIds

否則( $.type !== Type.REFERENCE ),它將不允許$.referenceClass的存在(除非您使用允許額外鍵的選項運行驗證)。

{
    type: Joi.string().valid( ...Hub.types ).required(),
    referenceClass: Joi.alternatives().conditional( 'type', {
        switch: [
            { is: Type.REFERENCE, then: Joi.string().valid( ...classIds ) },
        ],
    } ),
}

暫無
暫無

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

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