mongooseについて
MongoDB
とNode.js
を接続するのに、今まで使ってきたMongoDB
オフィシャルのmongodb
ドライバーとスキーマを設定するmongoose
ドライバーがありますが、ワタシ的にはオフィシャルのmongodb
で十分かなと思ったのですが、一応アプリ側でルールが必要なときもあるかなと、記事を探していたら、少し古いですがいい記事が見つかりました。
Node.js + Express 4.x + MongoDB(Mongoose)でRESTfulなjsonAPIサーバの作成を丁寧に解説する.+ テストクライアントを用いたAPIテストまで
内容はこれで、十分なのですが、node.js
やmongoose
が古いので、勉強がてら今風にコードも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
も使えると言うことなので、処理にasync
とawait
を挟んでいます、 await
に後ろに処理がなければ、実際必要がないのですが、非同期処理をしていることを動機づけするために、書いたほうがいいでしょう。 あっても害になりませんし、後から処理を付け足したときに、バグを誘発するのを防げます。
// mongoose.Promise = global.Promise
が必要かとつけていたんですが、なくても動きます。 問題がでたら、コメントを外せばいいかと思っていますが、ドライバー新しいので、defultで対応しているのかもしれません、この辺りは勉強不足ですみません。
mongoose
で Promsiseの日本語の記事が少ないので、参考になればと思いupしました。