Mongoose에서 CRUD 구현하기

Suyeon·2021년 3월 14일
6

Node.js

목록 보기
2/4

MongooseNode.js 환경에서 사용하는 MongoDB 기반의 ODM(object data model) 라이브러리

(참고)

  • postman: API 테스팅할 때 유용함

Model

  • 데이터 스키마 정의
  • validator와 같이 외부라이브러리를 함께 사용할 수 있음
  • statics: Static method
  • methods: Instance method
// src> models/user.js
const mongoose = require('mongoose');
const validator = require('validator'); 

const UserSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    trim: true,
  },
  email: {
    type: String,
    required: true,
    trim: true,
    validate(value) {
      if (!validator.isEmail(value)) {
        throw Error('Email is invalid!');
      }
    },
  },
  password: {
    type: String,
    required: true,
    trim: true,
    minLength: 7,
  },
    tokens: [ // multiple device에서 로그인 할 경우 
    {
      token: {
        type: String,
        required: true,
      },
    },
  ],
});

// Hash password
userSchema.pre('save', async function (next) {
  const salt = await bcrypt.genSalt();
  this.password = await bcrypt.hash(this.password, salt);
  next();
});

// Create and  push token to tokenArray
userSchema.methods.createToken = async function () {
  const user = this;
  const token = jwt.sign({ _id: user._id.toString() }, secret); // (*)
  user.tokens = user.tokens.concat({ token });
  await user.save();
  return token;
};

// static method to login user
userSchema.statics.login = async function (email, password) {
  const user = await this.findOne({ email });
  if (user) {
    const auth = await bcrypt.compare(password, user.password);
    if (auth) {
      return user;
    }
    throw Error('incorrect password');
  }
  throw Error('incorrect email');
};

const User = mongoose.model('User', UserSchema);

module.exports = User;

CRUD

  • req.body: 프론트로부터 받는 request.body
  • mongoose는 error status를 따로 잡아내지 않는다. 따라서 http request의 성공여부와 상관없이 default 값(200)을 보내기 때문에, 각 상황에 맞는 status 코드를 명시해줘야한다.
  • http status는 여기 참고
const express = require('express');
const router = new express.Router();
const User = require('../models/user');

// READ
router.get('/users', async (req, res) => {
  try {
    const users = await User.find({});
    res.send(users);
  } catch (err) {
    res.status(500).send();
  }
});

router.get('/users/:id', async (req, res) => {
  const _ID = req.params.id;
  try {
    const user = await User.findById(_ID);
    if (!user) res.status(404).send();
    res.send(user);
  } catch (err) {
    res.status(500).send();
  }
});

// CREATE
router.post('/users', async (req, res) => {
  const user = new User(req.body); // (*)
  try {
    await user.save();
    await res.status(201).send(user);
  } catch (err) {
    res.status(400).send(err);
  }
});

// UPDATE
router.patch('/users/:id', async (req, res) => {
  // Prevent to update when user send unallowed property
  const updates = Object.keys(req.body);
  const allowed = ['name', 'email', 'password'];
  const isValid = updates.every(update => allowed.includes(update));

  if (!isValid) {
    return res.status(400).send({ error: 'Invalid Updates.' });
  }

  try {
    const user = await User.findByIdAndUpdate(req.params.id, req.body, {
      new: true,
      runValidators: true,
    });
    if (!user) res.status(404).send();
    res.send(user);
  } catch (er) {
    res.status(400).send();
  }
});

// DELETE
router.delete('/users/:id', async (req, res) => {
  try {
    const user = await User.findByIdAndDelete(req.params.id);
    if (!user) res.status(404).send();
    res.send(user);
  } catch (err) {
    res.status(500).send();
  }
});

module.exports = router;
profile
Hello World.

1개의 댓글

comment-user-thumbnail
2021년 8월 2일

감사합니다 :)

답글 달기