![](/img/trans.png)
[英]What's the difference between Joi.object().keys() and append() methods in terms of adding more keys
[英]What is the difference between Joi.object() and Joi.object().keys()?
根據 Joi 文檔,您可以像這樣使用Joi.object()
:
const object = Joi.object({
a: Joi.number().min(1).max(10).integer(),
b: Joi.any()
});
但是您也可以使用Joi.object().keys()
編寫等效代碼,如下所示:
const object = Joi.object().keys({
a: Joi.number().min(1).max(10).integer(),
b: Joi.any()
});
兩者有什么區別?
如果您編寫一次架構,則不需要使用.keys()
。 正如他們的文檔所說,向 object 添加更多行(鍵)時使用.keys()
是“有用的”。
Joi.object().keys([schema]) notation
這與
Joi.object([schema])
基本相同,但是當您想要添加更多鍵時(例如多次調用keys()
),使用Joi.object().keys([schema])
更有用。 如果只添加一組鍵,則可以跳過keys()
方法,直接使用object()
。有些人喜歡使用
keys()
來使代碼更明確(這只是樣式)。
取自: https://github.com/hapijs/joi/blob/v8.0.3/API.md#joiobjectkeysschema-notation
我還發現了這個:
使用 joi 的方法有很多。 hapi 文檔無法顯示所有內容。 僅在將密鑰添加到 object 時才建議調用 keys(),因為它會創建另一個模式
@hapi/joi 文檔對此不是很清楚(在 v17.1.0 中)。 生成的模式具有相同的值,並且它們驗證相同。 查看源代碼,Object 類型是 Keys 類型,只是 object 不需要從定義它的 Any 類型復制密鑰。
Welcome to Node.js v12.16.1.
Type ".help" for more information.
> const Joi = require('@hapi/joi')
undefined
> const util = require('util')
undefined
> const object1 = Joi.object({
... a: Joi.number().min(1).max(10).integer(),
... b: Joi.any()
... });
undefined
> const object2 = Joi.object().keys({
... a: Joi.number().min(1).max(10).integer(),
... b: Joi.any()
... });
undefined
> util.format(object1) == util.format(object2)
true
> object1.validate({a: 1, b: 1})
{ value: { a: 1, b: 1 } }
> object2.validate({a: 1, b: 1})
{ value: { a: 1, b: 1 } }
> object1.validate({a: 0})
{
value: { a: 0 },
error: [Error [ValidationError]: "a" must be larger than or equal to 1] {
_original: { a: 0 },
details: [ [Object] ]
}
}
> object2.validate({a: 0})
{
value: { a: 0 },
error: [Error [ValidationError]: "a" must be larger than or equal to 1] {
_original: { a: 0 },
details: [ [Object] ]
}
}
> object1.validate({a: 1, b: 1, c:1})
{
value: { a: 1, b: 1, c: 1 },
error: [Error [ValidationError]: "c" is not allowed] {
_original: { a: 1, b: 1, c: 1 },
details: [ [Object] ]
}
}
> object2.validate({a: 1, b: 1, c:1})
{
value: { a: 1, b: 1, c: 1 },
error: [Error [ValidationError]: "c" is not allowed] {
_original: { a: 1, b: 1, c: 1 },
details: [ [Object] ]
}
}
> object1.validate({a: 1})
{ value: { a: 1 } }
> object2.validate({a: 1})
{ value: { a: 1 } }
> object1.validate({b: 1})
{ value: { b: 1 } }
> object2.validate({b: 1})
{ value: { b: 1 } }
> object1.validate({})
{ value: {} }
> object2.validate({})
{ value: {} }
.append(schema)
和.keys(schema)
之間的區別在文檔中也不清楚。 如果 schema 為空, .append(schema)
不會創建新副本,否則它只會返回.keys(schema)
的值。 我沒有發現這會有所作為的例子。
> util.format(Joi.object({}).keys({a:1})) == util.format(Joi.object({}).append({a:1}))
true
> util.format(Joi.object({}).unknown().keys({a:1})) == util.format(Joi.object({}).unknown().append({a:1}))
true
如文檔所述:
object.keys([架構])
設置或擴展允許的 object 鍵,其中:
- schema - 可選 object,其中每個鍵都分配有一個 joi 類型 object。 如果架構是 {},則不允許使用任何鍵。 如果架構是 null 或未定義,則允許任何鍵。 如果 schema 是帶有鍵的 object,則將鍵添加到任何先前定義的鍵(但如果先前允許所有鍵,則縮小選擇范圍)。
因此,通過調用Joi.object()
您首先創建一個允許任何鍵的模式,然后通過調用.keys([schema])
您擴展該模式(基本上與使用Joi.object([schema])
)
所以這兩個是等價的:
const a = Joi.object({ firstName: Joi.string() });
const b = Joi.object().keys({ firstName: Joi.string() });
您還可以擴展上面創建的兩個模式:
const aExtended = a.keys({ lastName: Joi.string() })
const bExtended = b.keys({ lastName: Joi.string() })
就像前面的答案中所述,有時出於代碼一致性的原因,使用.keys()
創建頂級模式,但最后我認為這是個人喜好問題。
當只有一組鍵直接在 object() 生成中定義我們的模式時,我們也可以在不使用 keys() 的情況下定義模式,如下所示:
const schema = Joi.object({
username: Joi.string().alphanum().min(3).max(16).required(),
password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/).min(6).required()
}).with('username', 'password');
那么為什么要使用帶有單個鍵集的 keys() 呢?
保持你的代碼一致。 在整個 Joi 文檔中,甚至在單個鍵對象上都使用了 keys()。
使用鍵()
正如我們之前提到的,如果我們定義單個鍵集,則不必使用 keys()。 此外,如果在 Joi.object() 上沒有定義任何鍵,那么任何鍵都是有效的:沒有規則可以使我們使用 Joi 模式測試的任何 object 無效。 我們還可以選擇在模式的原始定義之后添加鍵。 以下來自 Joi 文檔的示例演示了這一點:
//define base object
const base = Joi.object().keys({
a: Joi.number(),
b: Joi.string()
});
// add a c key onto base schema
const extended = base.keys({
c: Joi.boolean()
});
您可能已經注意到,我們在這里定義常量。 Joi 對象是不可變的,因此擴展基本模式將產生全新的 object。 在這里,我們將 object 保存為常量擴展。 我們還介紹了上面的 Joi.boolean() 規則,它在測試復選框和其他開關時非常方便,我們需要一個真或假值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.