在数据存储到数据库之前验证数据格式的一个聪明的方法是使用 Mongoose 提供的validation功能。
我们可以为模式中的每个字段定义特定的验证规则:

  1. const noteSchema = new mongoose.Schema({
  2. content: {
  3. type: String,
  4. minLength: 5,
  5. required: true
  6. },
  7. date: {
  8. type: Date,
  9. required: true
  10. },
  11. important: Boolean,
  12. })

minLength 和 required 验证器是内置的
添加错误处理

  1. -- snip --
  2. app.post('/api/notes', (request, response, next) => {
  3. const body = request.body
  4. if (!body.content) {
  5. return response.status(400).json({
  6. error: 'content missing'
  7. })
  8. }
  9. const note = new Note({
  10. content: body.content,
  11. important: body.important || false,
  12. date: new Date(),
  13. })
  14. note.save().then(savedNote => {
  15. response.json(savedNote)
  16. })
  17. .catch(error => next(error))
  18. })
  19. -- snip --
  20. const errorHandler = (error, request, response, next) => {
  21. console.log(error.message)
  22. if (error.name === 'CastError' && error.kind === 'ObjectId') {
  23. return response.status(400).send({ error: 'malformatted id' })
  24. } else if (error.name === 'ValidationError') {
  25. return response.status(400).json({ error: error.message })
  26. }
  27. next(error)
  28. }
  29. -- snip --

Promise chaining

许多的路由处理程序会将响应数据通过隐式地调用 toJSON 方法,将 response.json 数据格式转换成正确的格式。
我们可以用promise链显式地写出来

  1. app.post('/api/notes', (request, response, next) => {
  2. // ...
  3. note
  4. .save()
  5. .then(savedNote => savedNote.toJSON())
  6. .then(savedAndFormattedNote => {
  7. response.json(savedAndFormattedNote)
  8. })
  9. .catch(error => next(error))
  10. })

Deploying the database backend to production

将数据库后端部署到生产坏境
我们在文件 .env中定义了用于开发的环境变量。 但是在生产环境中定义数据库 URL 的环境变量应该使用
heroku config:set 命令来设置 Heroku。

  1. heroku config:set MONGODB_URI='mongodb+srv://fullstack:密码@cluster0-ostce.mongodb.net/note-app?retryWrites=true'

如果报错:UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the first certificate
给命令终端设置代理即可

Exercises 3.19.-3.21.

验证唯一性
Mongoose没有内置验证唯一性的验证器,可以使用mongoose-unique-validator
安装

  1. yarn add mongoose-unique-validator
  2. # 或者
  3. npm install mongoose-unique-validator

使用

  1. var mongoose = require('mongoose');
  2. var uniqueValidator = require('mongoose-unique-validator');
  3. // Define your schema as normal.
  4. var userSchema = mongoose.Schema({
  5. username: { type: String, required: true, unique: true },
  6. email: { type: String, index: true, unique: true, required: true },
  7. password: { type: String, required: true, minLength: 8}
  8. });
  9. // Apply the uniqueValidator plugin to userSchema.
  10. userSchema.plugin(uniqueValidator);

ValidationError 错误处理

  1. const errorHandler = (error, request, response, next) => {
  2. console.log(error.message)
  3. if (error.name === 'CastError' && error.kind === 'ObjectId') {
  4. return response.status(400).send({ error: 'malformatted id' })
  5. } else if (error.name === 'ValidationError') {
  6. return response.status(400).send({ error: error.message })
  7. }
  8. next(error)
  9. }

在前端获取错误信息
如果不知道,就要用console.dir(error)把错误信息打出来查看结构

  1. personService.create(newObject)
  2. .then(response => {
  3. -- snip --
  4. })
  5. .catch(error => console.log(error.response.data.error))

Mongoose的upate默认是不开启验证的,要开启验证需添加如下参数

  • runValidators: true,
  • context: ‘query’ ```javascript const opts = { new: true, runValidators: true, context: ‘query’ }

Person.findByIdAndUpdate(request.params.id, person, opts) .then(updatedPerson => { response.json(updatedPerson) }) .catch(error => next(error))

  1. <a name="XSd8I"></a>
  2. ### Lint
  3. 通常,lint 或 linter 是检测和标记编程语言中的错误,包括文本错误的一种工具。 lint-like 这个术语有时用于标记可疑的语言使用情况。 类似 lint 的工具通常对源代码执行静态分析。<br />在 JavaScript 的世界里,目前主要的静态分析工具(又名“ linting”)是[ESlint](https://eslint.org/)<br />在后端项目中,将ESlint安装为开发依赖
  4. ```bash
  5. npm install eslint --save-dev
  6. # 或者
  7. yarn add eslint --dev

使用命令初始化eslint默认配置

  1. node_modules/.bin/eslint --init

image.png
项目根目录会生成一个.eslintrc.js文件

  1. module.exports = {
  2. 'env': {
  3. 'browser': true,
  4. 'commonjs': true,
  5. 'es2021': true
  6. },
  7. 'extends': 'eslint:recommended',
  8. 'parserOptions': {
  9. 'ecmaVersion': 12
  10. },
  11. 'rules': {
  12. 'indent': [
  13. 'error',
  14. 4
  15. ],
  16. 'linebreak-style': [
  17. 'error',
  18. 'unix'
  19. ],
  20. 'quotes': [
  21. 'error',
  22. 'single'
  23. ],
  24. 'semi': [
  25. 'error',
  26. 'never'
  27. ]
  28. }
  29. }

将缩进改为2个空格

  1. 'indent': [
  2. 'error',
  3. 2
  4. ],

通过Eslint检查一个文件,如index.js

  1. node_modules/.bin/eslint index.js

创建一个单独的npm脚本命令, 检查当面目录所有文件

  1. {
  2. // ...
  3. "scripts": {
  4. // ...
  5. "lint": "eslint ."
  6. },
  7. // ...
  8. }

创建.eslintignore文件,将build添加进去,检查时忽略build文件夹
执行命令 npm run lintyarn lint 检查代码

安装插件ESLint, 它会连续执行代码检查命令,并在vscode中用红线将错误标示出来
image.png
继续在 .eslintrc.js添加规则

  1. {
  2. // ...
  3. 'rules': {
  4. // ...
  5. 'eqeqeq': 'error',
  6. 'no-trailing-spaces': 'error',
  7. 'object-curly-spacing': [
  8. 'error', 'always'
  9. ],
  10. 'arrow-spacing': [
  11. 'error', { 'before': true, 'after': true }
  12. ],
  13. 'no-console': 0
  14. },
  15. }

修改配置后,用命令行执行lint,验证配置是否正确