博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
node mongoose_如何使用Mongoose插件在Express.js应用程序中记录Node.js API
阅读量:2526 次
发布时间:2019-05-11

本文共 8579 字,大约阅读时间需要 28 分钟。

node mongoose

This tutorial will require prior knowledge of the Object Relational Mapping (ORM) technique

本教程将需要对象关系映射(ORM)技术的先验知识

介绍 (Introduction)

As your application grows, logging becomes a crucial part to keep track of everything. It is especially important for debugging purposes.

随着应用程序的增长,日志记录成为跟踪所有内容的关键部分。 这对于调试目的尤其重要。

Nowadays there are already logging modules available at npm. These modules can store logs in a file in different formats, or levels. We are going to discuss the API logging in your Node.js Express app using the popular ORM Mongoose.

如今,npm已经有可用的日志记录模块。 这些模块可以将日志以不同的格式或级别存储在文件中。 我们将讨论使用流行的ORM猫鼬在Node.js Express应用中记录API的过程。

So how you would create a Mongoose plugin that will do logging for you in a cleaner way and make API logging easy?

那么,如何创建一个Mongoose插件 ,该插件将以更简洁的方式为您记录日志并简化API日志记录?

猫鼬的插件是什么? (What is a plugin in Mongoose?)

In Mongoose, schemas are pluggable. A plugin is like a function that you can use in your schema and reuse again and again over schema instances.

在Mongoose中,模式是可插入的。 插件就像可以在架构中使用并在架构实例上反复使用的功能。

Mongoose also provides global plugins which you can use for all schemas. For example, we are going to write a plugin that will create a diff of two jsons and write to mongodb.

Mongoose还提供了可用于所有模式的全局插件 。 例如,我们将要编写一个插件,该插件将创建两个jsonsdiff并写入mongodb

步骤1:创建基本日志架构模型 (Step 1: Creating a Basic Log Schema Model)

Let’s create a basic log schema with the following six properties:

让我们创建一个具有以下六个属性的基本日志架构:

  • Action: As per its name, this will be a course of action of the API whether it is create update delete or something else.

    动作:顾名思义,无论是create update delete还是其他操作,这都是API的一种动作。

  • Category: API category. For example doctors and patients. It is more like a class.

    类别: API类别。 例如医生和病人。 它更像是一堂课。

  • CreatedBy: User who is using the API or invoked it.

    CreatedBy:使用或调用API的用户。

  • Message: Here you can include any kind of message you want to show that will make sense or help during debugging.

    消息:您可以在此处包括任何想要显示的消息,这些消息在调试过程中将是有意义的或有帮助的。

  • Diff: This is the main property which will have the diff of two JSONs

    差异 这是主要属性,将具有两个JSON差异

You can add more fields if you want that make sense for your own application. A schema can be changed and upgraded according to requirements.

如果您希望自己的应用程序有意义,则可以添加更多字段。 可以根据需求更改和升级架构。

Here is our model: models/log.js

这是我们的模型: models/log.js

const mongoose = require('mongoose')const Schema = mongoose.Schemaconst { ObjectId } = Schemaconst 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之间的差 (Step 2: Write a function to get the difference between 2 JSONs)

So the next step is that you need a reusable function that will create a diff of two JSONs on the fly.

因此,下一步是您需要一个可重用的函数,该函数将动态创建两个JSON的diff

Let's call it diff.js

我们称之为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)}

I have used , which is a popular library, to provide the same functionality.

我使用了 (这是一个受欢迎的库)来提供相同的功能。

Let's break down the above function and see what's going on:

让我们分解上面的功能,看看发生了什么:

  • _.transform: It’s an alternative to .reduce for arrays. Basically, it will iterate over your object keys and values. It provides an accumulator which is the first argument. result is the accumulator and it is mutable.

    _.transform:这是一种替代.reduce对数组。 基本上,它将遍历对象的keysvalues 。 它提供了一个accumulator ,它是第一个参数。 result 是累加器,并且是可变的。

  • _.isEqual: Performs a deep comparison between two values to determine if they are equivalent.

    _.isEqual:在两个值之间进行深度比较以确定它们是否等效。

isEqual: This method supports comparing arrays, array buffers, booleans, date objects, error objects, maps, numbers, Object objects, regexes, sets, strings, symbols, and typed arrays. Object objects are compared by their own, not inherited, enumerable properties. Functions and DOM nodes are compared by strict equality, i.e. ===.

isEqual :此方法支持比较数组,数组缓冲区,布尔值,日期对象,错误对象,映射,数字, Object对象,正则表达式,集合,字符串,符号和类型化数组。 Object对象通过它们自己的(而不是继承的)可枚举属性进行比较。 通过严格相等(即===比较函数和DOM节点。

Here we are iterating over each object property and value and comparing it with our old/prev object.

在这里,我们迭代每个对象的属性和值,并将其与我们的旧对象/上一个对象进行比较。

If the value of the current object is not equal to a value of the same property in the previous object: base[key] and if that value is the object itself, we call the function changes recursively until it gets a value which will be finally stored in result as result[key] = value.

如果value当前对象的不等于在以前的对象相同的属性值: base[key] ,如果该值是对象本身,我们调用函数的changes 递归 ,直到它得到,这将是最后的值存储在result中, resultresult[key] = value

第三步:创建一个使用diff的插件并将其保存到数据库 (Step3: Create a plugin to use diff and save it to database)

Now we need to keep track of the previous document in the database and create a diff before saving to mongodb.

现在,我们需要跟踪数据库中的上一个document ,并在保存到mongodb之前创建一个diff

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

In Mongoose, there are different hooks available. For now, we need to use the and methods available on the schema.

在猫鼬中,有不同的钩子可用。 现在,我们需要使用架构上可用的方法。

this.isNew() : If you are creating the new document then just return next() middleware.

this.isNew() :如果要创建新文档,则只需返回next()中间件。

In schema.post('init') :

schema.post('init')

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

Mongoose Models inherit from Documents, which have a toObject() method. It will convert a document into an Object() and transform:false is for not allowing to transform the return object.

猫鼬Model继承自Document ,后者具有toObject()方法。 它将document转换为Object()并进行transform:false表示不允许转换返回对象。

步骤4:用法-如何在express.js API中使用 (Step 4: Usage — How to use in express.js API)

In your main server.js or app.js :

在您的主要server.jsapp.js

Initialise a global so that it will be available for all schemas. You can also use it for a particular schema by initializing it in the schema model.

初始化一个全局以便它可用于所有模式。 您还可以通过在模式模型中对其进行初始化,将其用于特定模式。

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

Here is a basic example of user update API:

这是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)       })}

结论 (Conclusion)

In this tutorial, you learned how to create a Mongoose plugin and use it to log the changes in your API. You can do a lot more with plugins to build a robust node application.

在本教程中,您学习了如何创建Mongoose插件并使用它来记录API中的changes 。 您可以使用插件做更多的事情来构建强大的节点应用程序。

Here are resources to learn more about Mongoose and plugin usage:

以下是一些资源,以了解有关Mongoose和插件用法的更多信息:

  • 80/20 Guide to mongoose plugins:

    80/20猫鼬插件指南: :

I hope you find this tutorial useful, feel free to reach if you have any questions.

希望本教程对您有所帮助如有任何疑问,请随时与我们联系。

Follow to get notified whenever I publish a new post.

每当我发布新帖子时,请关注以获得通知。

Don’t hesitate to clap if you considered this a worthwhile read!

如果您认为这值得一读,请随时鼓掌!

Originally published at on September 2, 2018.

最初于年9月2日发布在 。

翻译自:

node mongoose

转载地址:http://hjkzd.baihongyu.com/

你可能感兴趣的文章
2.python的基本数据类型
查看>>
python学习笔记-day10-01-【 类的扩展: 重写父类,新式类与经典的区别】
查看>>
查看端口被占用情况
查看>>
浅谈css(块级元素、行级元素、盒子模型)
查看>>
Ubuntu菜鸟入门(五)—— 一些编程相关工具
查看>>
PHP开源搜索引擎
查看>>
12-FileZilla-响应:550 Permission denied
查看>>
ASP.NET MVC 3 扩展生成 HTML 的 Input 元素
查看>>
LeetCode 234. Palindrome Linked List
查看>>
编译HBase1.0.0-cdh5.4.2版本
查看>>
结构体指针
查看>>
迭代器
查看>>
Food HDU - 4292 (结点容量 拆点) Dinic
查看>>
Ubuntu安装Sun JDK及如何设置默认java JDK
查看>>
[经典算法] 排列组合-N元素集合的M元素子集
查看>>
Codeforces 279D The Minimum Number of Variables 状压dp
查看>>
打分排序系统漫谈2 - 点赞量?点赞率?! 置信区间!
查看>>
valgrind检测linux程序内存泄露
查看>>
Hadoop以及组件介绍
查看>>
1020 Tree Traversals (25)(25 point(s))
查看>>