3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

mongoose と Promise - Express MongoDBでjsonAPIサーバをつくる

Posted at

mongooseについて

MongoDBNode.jsを接続するのに、今まで使ってきたMongoDBオフィシャルのmongodbドライバーとスキーマを設定するmongooseドライバーがありますが、ワタシ的にはオフィシャルのmongodbで十分かなと思ったのですが、一応アプリ側でルールが必要なときもあるかなと、記事を探していたら、少し古いですがいい記事が見つかりました。

Node.js + Express 4.x + MongoDB(Mongoose)でRESTfulなjsonAPIサーバの作成を丁寧に解説する.+ テストクライアントを用いたAPIテストまで

内容はこれで、十分なのですが、node.jsmongooseが古いので、勉強がてら今風にコードもPromise風味で書き直してみました。
内容わかりやすいので、リンクを見てもらえればと思います。(笑)

使用ライブラリのバージョン

パッケージ バージョン
MongoDB v4.0.4
Node.js v11.4.0

ディレクトリツリー

.
├── app
│   ├── models
│   │   └── user.js
│   └── server.js
├── package.json
└── yarn.lock

package.json

{
  "name": "02",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "body-parser": "^1.18.3",
    "express": "^4.16.4",
    "mongoose": "^5.4.1"
  }
}

user.js

const mongoose = require('mongoose')
const Schema = mongoose.Schema

const UserSchema = new Schema({
  twitter_id: { type: String, required: true, unique: true },
  name: String,
  age: Number
})

module.exports = mongoose.model('User', UserSchema)

server.js


const express = require('express')
const app = express()
const bodyParser = require('body-parser')
const port = process.env.PORT || 3000
const router = express.Router()
const mongoose = require('mongoose')
const User = require('./models/user')

// mongoose.Promise = global.Promise
mongoose.connect('mongodb://localhost:27017/jsonAPI', { useNewUrlParser: true, useCreateIndex: true })


app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json())
app.use('/api', router)

router.use((req, res, next) => {
  console.info('Something is happening.')
  next()
})
router.get('/', (req, res) => {
  res.json({ message: "Succesfully /api a test message."})
})
router.route('/users')
  .post(async(req, res) => {
    const user = new User()

    user.twitter_id = req.body.twitter_id
    user.name = req.body.name
    user.age = req.body.age

    await user.save()
      .then(result => {
        res.json({ message: "User created"})
      })
      .catch(err => {
        res.send(err)
        console.error(err)
      })
  })
  .get(async(req, res) => {
    await User.find({})
      .exec()
      .then(users => {
        res.json(users)
      })
      .catch(err => {
        res.send(err)
      })
  })

router.route('/users/:user_id')
  .get(async(req, res) => {
    await User.findById(req.params.user_id)
      .exec()
      .then(user => {
        res.json(user)
      })
      .catch(err => {
        res.send(err)
      })
  })
  .put(async(req, res) => {
    const result =  await User.findById(req.params.user_id)
      .then(user => {
        user.twitter_id = req.body.twitter_id
        user.name = req.body.name
        user.age = req.body.age
        return user
      })
      .catch(err => {
        res.send(err)
      })
    console.log('result', result)


      await result.save()
      .then(result => {
        res.json({ message: "User created"})
      })
      .catch(err => {
        res.send(err)
      })

  })
  .delete(async(req, res) => {
    await User.deleteOne({
      _id: req.params.user_id
    })
      .exec()
      .then(() => res.json({ message: "Successfully deleted"}))
      .catch(err => res.send(err))
  })

app.listen(port)
console.info('listen on port: ' + port)

簡単に説明しますと、Promiseが使えるとして、返り値はthen,catchで処理することになりますが、Promsiseが使えると言うことは、awaitも使えると言うことなので、処理にasyncawaitを挟んでいます、 awaitに後ろに処理がなければ、実際必要がないのですが、非同期処理をしていることを動機づけするために、書いたほうがいいでしょう。 あっても害になりませんし、後から処理を付け足したときに、バグを誘発するのを防げます。

// mongoose.Promise = global.Promise が必要かとつけていたんですが、なくても動きます。 問題がでたら、コメントを外せばいいかと思っていますが、ドライバー新しいので、defultで対応しているのかもしれません、この辺りは勉強不足ですみません。

mongooseで Promsiseの日本語の記事が少ないので、参考になればと思いupしました。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?