Отметить все свойства как требуется или нет Joi - PullRequest
0 голосов
/ 07 марта 2020

Я создаю Express API и использую @ hapi / joi для проверки. Однако я нахожусь в следующей ситуации: если я хочу проверить нового пользователя, все свойства в схеме должны быть обязательными, но если клиент хочет изменить пользователя, эти свойства должны быть необязательными, поскольку только клиент знает, что свойства это изменит. Так что, если у меня есть эта схема для новых пользователей:

function validateUser(user) {
  const schema = Joi.object().keys({
    name: Joi.string().required(),
    lastName: Joi.string().required(),
    email: Joi.string().email().required(),
    password: Joi.string().required(),
    address: Joi.string().required(),
    city: Joi.string().required(),
    district: Joi.string().required()
});

  return schema.validate(user);
}

Поскольку все свойства обязательны, когда я хочу использовать схему с такими же свойствами, но все необязательно, я должен жестко написать другую схему, где все свойства не являются обязательными. Есть ли способ или вариант Joi, чтобы избежать избыточного кода? Как параметр isNew, переданный в функцию validateUser, чтобы применить его к схеме?

1 Ответ

0 голосов
/ 08 марта 2020

Я полагаю, вы решаете проблему неправильно. Схема должна, как правило, отображать ваши типы в БД. например, если требуется имя, оно всегда будет требоваться независимо от того, будет ли оно создано или обновлено. Так что в случае обновления вы получите элемент из базы данных и примените изменения к нему, а затем отправите его для проверки.

Если вы действительно хотите сделать это таким образом, вы можете передать контекст своей функции проверки доступ к которому можно получить из вашей схемы joi, используя знак $. Здесь у вас есть два варианта: либо применить условие if else для каждого свойства, которое сделает вашу схему неприглядной, либо иметь все вместе две версии схемы и выбирать в зависимости от значения переданного контекста. Как то так

const Joi = require("@hapi/joi");

const schemaA = Joi.object().keys({
  "name": Joi.string().required(),
  "lastName": Joi.string().required(),
  "email": Joi.string().email().required(),
  "password": Joi.string().required(),
  "address": Joi.string().required(),
  "city": Joi.string().required(),
  "district": Joi.string().required()
});

const schemaB = Joi.object().keys({
  "name": Joi.string(),
  "lastName": Joi.string(),
  "email": Joi.string().email(),
  "password": Joi.string(),
  "address": Joi.string(),
  "city": Joi.string(),
  "district": Joi.string()
});

function ChooseSchema() {
  return Joi.when(Joi.ref("$isNew"), {
    "is": true,
    "then": schemaA,
    "otherwise": schemaB
  });
}

console.log(ChooseSchema().validate({"name": "ashish"}, {"context": {"isNew": true}}));
console.log(ChooseSchema().validate({"name": "ashish"}, {"context": {"isNew": false}}));


...