Как зарегистрировать API Node.js в Express.js с помощью плагинов Mongoose

kak zaregistrirovat api nodejs v expressjs s pomoshhyu plaginov mongoose

Для этого учебнику понадобятся предварительные знания техники реляционного отображения объектов мангуста (ORM).

Введение

По мере роста вашей программы ведение журнала становится важной частью отслеживания всего. Это особенно важно для целей отладки.

Сейчас на npm уже доступны модули регистрации. Эти модули могут сохранять журналы в файле в разных форматах или уровнях. Мы собираемся обсудить регистрацию API в вашем приложении Node.js Express с помощью популярного ORM Mongoose.

Итак, как бы вы создали a Плагин Mongoose это сделает журналирование по вам более чистым способом и облегчит протоколирование API?

Что такое плагин в Mongoose?

В Mongoose схемы можно подключать. Плагин похож на функцию, которую можно использовать в своей схеме и использовать снова и снова в экземплярах схемы.

Мангуст также обеспечивает глобальные плагины которую можно использовать для всех схем. К примеру, мы собираемся написать плагин, который создаст a diff из двух jsons и написать к mongodb.

Шаг 1: Создание базовой модели схемы журнальчика

Давайте создадим базовую схему журнала со следующими шестью свойствами:

  • Действие: Согласно его названию, это будет курсом действий API, независимо от того create update delete или что-то другое.
  • категория: Категория API. К примеру, врачи и пациенты. Это больше похоже на класс.
  • Создано: Пользователь, использующий API или вызывающий его.
  • Сообщение: Здесь вы можете включить любой тип сообщения, которое вы хотите показать, что будет иметь смысл или поможет во время отладки.
  • разница: Это главное свойство, которым будет обладать разница из двух JSON

Вы можете добавить больше полей, если хотите, чтобы они имели смысл для вашего собственного приложения. Схема может быть изменена и обновлена ​​в соответствии с требованиями.

Вот наша модель: models/log.js

const mongoose = require('mongoose')
const Schema = mongoose.Schema
const { ObjectId } = Schema

const LogSchema = new Schema({
  action: { type: String, required: true },
  category: { type: String, required: true },
  createdBy: { type: ObjectId, ref: 'Account', required: true },
  message: { type: String, required: true },
  diff: { type: Schema.Types.Mixed },
},{
  timestamps: { createdAt: 'createdAt', updatedAt: 'updatedAt' },
})

LogSchema.index({ action: 1, category: 1 })

module.exports = mongoose.model('Log', LogSchema)

Шаг 2: Напишите функцию, чтобы получить разницу между 2 JSON

Следующий шаг состоит в том, что вам нужна функция многоразового использования, которая создаст a diff двух JSON на лету.

Назовем это diff.js

const _ = require('lodash')

exports.getDiff = (curr, prev) => {
  function changes(object, base) {
    return _.transform(object, (result, value, key) => {
      if (!_.isEqual(value, base[key]))
        result[key] = (_.isObject(value) && _.isObject(base[key])) ?                 changes(value, base[key]) : value
    })
 }
 return changes(curr, prev)
}

Я использовал lodash, которая является популярной библиотекой, чтобы обеспечить ту же функциональность.

Давайте разберем вышеупомянутую функцию и посмотрим, что происходит:

  • _.transform: Это альтернатива .reduce для массивов. По сути он перебирает ваш объект keys и values. Это обеспечивает accumulator что является первым доводом. result является аккумулятором и меняется.
  • _.isEqual: Выполняет глубокое сравнение двух значений, чтобы определить, эквивалентны ли они.

равно: Этот метод поддерживает сравнение массивов, буферов массивов, логических значений, объектов даты, объектов ошибок, карт, чисел, Object объекты, регулярные выражения, наборы, строчки, символы и типизированные массивы. Object объекты сравниваются по своим собственным, а не унаследованным перечисляемым свойствам. Функции и узлы DOM сравниваются по строгому равенству, т.е. ===.

Здесь мы перебираем каждое свойство и значение объекта и сравниваем его с нашим старым/предыдущим объектом.

Если value текущего объекта не равно значению того же свойства в предыдущем объекте: base[key] и если этим значением является сам объект, мы вызываем функцию changes рекурсивно пока он не получит значение, которое наконец будет сохранено result как result[key] = value.

Шаг 3: Создайте плагин для использования diff и сохраните его в базе данных

Теперь нам нужно следить за предыдущим document в базе данных и создайте a diff перед сохранением до mongodb.

const _ = require('lodash')
const LogSchema = require('../models/log')
const { getDiff } = require('../utils/diff')

const plugin = function (schema) {
  schema.post('init', doc => {
    doc._original = doc.toObject({transform: false})
  })
  schema.pre('save', function (next) {
    if (this.isNew) {
      next()
    }else {
      this._diff = getDiff(this, this._original)
      next()
    }
})

  schema.methods.log = function (data)  {
    data.diff = {
      before: this._original,
      after: this._diff,
    }
    return LogSchema.create(data)
  }
}

module.exports = plugin

В Mongoose доступны разные крючки. Пока нам нужно использовать init и save доступны на схеме методы.

this.isNew() : Если вы создаете новый документ, просто вернитесь next() промежуточное программное обеспечение

в schema.post('init') toObject():

doc._original = doc.toObject({transform: false})

Мангуст Modelнаследуют от Documents, которые имеют a toObject() метод. Это превратит a document в Object() и transform:false предназначен для того, чтобы не позволить трансформировать возвращаемый объект.

Шаг 4: Использование — Как использовать API в express.js

В вашем основном server.js или app.js :

Инициализируйте глобальный плагин, чтобы он был доступен для всех схем. Можно также использовать его для определенной схемы, инициализировав его в модели схемы.

const mongoose = require('mongoose')

mongoose.plugin(require('./app/utils/diff-plugin'))

Вот основной пример user API обновления:

const User = require('../models/user')

exports.updateUser = (req, res, next) => {
  return User.findById(req.params.id)
    .then(user => {
        if (!user)
           throw new Error('Target user does not exist. Failed to update.')
       const { name } = req.body
       if (name) user.name = name
       return user.save()
     })
     .then(result => {
       res.json(result)
       return result
     })
     .catch(next)
     .then(user => {
         if (user && typeof user.log === 'function') { 
            const data = {
              action: 'update-user',
              category: 'users',
              createdBy: req.user.id,
              message: 'Updated user name',
         }
         return user.log(data)
     }
     }).catch(err => {
         console.log('Caught error while logging: ', err)
       })
}

Вывод

В этом учебнике вы узнали, как создать плагин Mongoose и использовать его для регистрации changes в вашем API. Вы можете сделать гораздо больше с помощью плагинов для создания надежной программы узла.

Вот ресурсы, чтобы узнать больше о Mongoose и использования плагинов:

Надеюсь, это руководство вам будет полезным. Если у вас возникнут вопросы, не стесняйтесь обращаться.

Следите за Шайлешем Шехаватом, чтобы получать уведомления, когда я публикую новую публикацию.

Не стесняйтесь аплодировать, если вы считаете, что это стоит прочесть!

Первоначально опубликовано на 101node.io 2 сентября 2018 года.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *