2

arangodb 3.0.2 を使用していますが、スキーマの更新/パッチ適用時に joi の検証に問題があります。

このようなユーザースキーマがあります

_key: joi.string(),
name: joi.string().required(),
username: joi.string(),
email: joi.string().required(),
profilePicture: joi.string(),
provider: joi.object().keys({
  name: joi.string(),
  id: joi.string()
}),
interest: joi.array().items(joi.string()),
level: joi.number().default(0)

新しい新しいユーザーを作成し、ステータスなどの不明なフィールドを追加しようとすると、エラーがスローされます。

しかし、ユーザーを更新して不明なフィールドを追加しても、エラーは発生しません。リクエストスキーマを検証しないためです。

コレクションに既に存在するフィールドを無視して、ユーザーを更新/パッチするときにスキーマを検証する方法は?


ルートの更新:

router.post(function (req, res) {
  const user = req.body;
  let provider = user.provider.name;
  let id = user.provider.id;
  let meta;
  try {
    meta = users.save(user);
  } catch (e) {
    if (e.isArangoError && e.errorNum === ARANGO_DUPLICATE) {
      throw httpError(HTTP_CONFLICT, e.message);
    }
    throw e;
  }
  Object.assign(user, meta);
  res.status(201);
  res.set('location', req.makeAbsolute(
    req.reverse('detail', {key: user._key})
  ));
  res.send(user);
}, 'create')
.body(User, 'The user to create.')
.response(201, User, 'The created user.')
.error(HTTP_CONFLICT, 'The user already exists.')
.summary('Create a new user')
.description(dd`
  Creates a new user from the request body and
  returns the saved document.
`);

router.patch(':key', function (req, res) {
  const key = req.pathParams.key;
  const patchData = req.body;
  let user;
  try {
    users.update(key, patchData);
    user = users.document(key);
  } catch (e) {
    if (e.isArangoError && e.errorNum === ARANGO_NOT_FOUND) {
      throw httpError(HTTP_NOT_FOUND, e.message);
    }
    if (e.isArangoError && e.errorNum === ARANGO_CONFLICT) {
      throw httpError(HTTP_CONFLICT, e.message);
    }
    throw e;
  }
  res.send(user);
}, 'update')
.pathParam('key', keySchema)
.body(joi.object().description('The data to update the user with.'))
.response(User, 'The updated user.')
.summary('Update a user')
.description(dd`
  Patches a user with the request body and
  returns the updated document.
`);

ご覧のとおり、これが私のルートです。新しいユーザーを投稿すると、ユーザー スキーマが検証されるため、不明なフィールドを追加するとエラーが発生します。

ただし、ユーザーにパッチを適用すると、ユーザースキーマは検証されません。「本体」ではユーザースキーマとして設定されていないためです。しかし、そこにユーザースキーマを追加すると、必須フィールドがチェックされるため、既知のフィールドにパッチを適用することはできません。

4

1 に答える 1

1

.post()作成 (ルート) と更新 (ルート)の両方で特定のスキーマを確保したい場合は、.patch()インラインで 2 回記述するのではなく、スキーマを 1 回だけ定義して両方のルートで参照するようにしてください.body()( DRY 原則)。

let userSchema = joi.object().keys({
  _key: joi.string(),
  name: joi.string().required(),
  username: joi.string(),
  email: joi.string().required(),
  profilePicture: joi.string(),
  provider: joi.object().keys({
    name: joi.string(),
    id: joi.string()
  }),
  interest: joi.array().items(joi.string()),
  level: joi.number().default(0)
});

router.post(...)
  .body(userSchema)

router.patch(...)
  .body(userSchema)

User変数に格納され、POST ルートで使用される次のようなスキーマを実際に定義したようです。

.body(User, 'The user to create.')

ただし、PATCH ルートではスキーマを使用しません。

.body(joi.object().description('The data to update the user with.'))

それreq.bodyがオブジェクトであることを保証するだけで、スキーマを強制しません。

于 2016-09-14T13:12:24.487 に答える