LoginSignup
2
4

More than 3 years have passed since last update.

Node.js(Express)からmongoDBをREST API的にたたく2019

Last updated at Posted at 2019-06-07

やりたいこと

mongoDBを使って、Key=Valueの1ペアを格納して、Keyで値がとれて、KeyでUpdateもDeleteもできる。
ただそれだけのシンプルなDBがほしいから作りました。

_id ではなく Key というのがみそです。

例えば、name=ドルリーレーン とやればそれをただ記録してくれる。nameは? といえばドルリーレーンと返してくれる。othername=エラリークイーン とやれば追加で記録してくれて、othernameは? といえばエラリークイーンと返してくれる。

本当に簡単な実験的な仕組みをつくりたいときにこういうシンプルなDBがあると便利なので作りました。

※ 認証などの仕組みはいっさいないのでローカルのテストとか閉じたネットワークでお試しください
※ Keyは何個でも格納できますが同じKeyが複数あってもエラーにもなりません。いいんです実験用なので。

ついでに expree + mondgoDB の良いサンプルにもなると思いますので公開しておきます

使い方はこうです

$ curl http://xxx/data -X POST -d "name=mio"  ← データ挿入
$ curl http://xxx/data/name  ← mio が返ってくる
$ curl http://xxx/data/  ← 格納している全データが返ってくる
$ curl http://xxx/data/name -X PUT -d "name=miomio"  ← nameの値が更新される
$ curl http://xxx/data/name -X DELETE  ← nameの値が削除される

環境+コード含めて解説

mongoDBのインストール!

EC2 Amazon Linuxでやっていますが他の環境では適宜読み替えを。

sudo vi /etc/yum.repos.d/mongodb-org-4.0.repo
[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc
sudo yum install -y mongodb-org

確認。

mongo -version

OKですね。次に進みます。

Expressのサーバ立ち上げ

Node.jsは入ってること前提で。

npm install -g express-generator
express -e site
cd site
npm install
PORT=8080 npm start

個人的な色々な理由でポート8080で立ち上げてますがこの辺りはご自由に。。

とりあえずブラウザでアクセスしてみて確認。良く見慣れたこれが出ます。

image.png

OKです。
Ctrl+Cとかでサーバは止めておきます。

ExpressからmongoDBの操作のアプリを作る。

Expressのフォルダ(今回はsite)にいる状態て mongodb を扱うためのライブラリをインストール。

npm install mongodb

REST APIの本題であるdata.jsを作ります。
※コードが冗長ですみません…

routes/data.js
ar express = require('express');
var router = express.Router();

var MongoClient = require('mongodb').MongoClient;
var ObjectID = require('mongodb').ObjectID;
var url = "mongodb://localhost:27017/";

// GET find
router.get( '/', function ( req, res ) {
  MongoClient.connect(url, { useNewUrlParser: true }, function(err, client) {
    client.db('db').collection("restapi").find().toArray( function(err, r) {
      client.close();
      res.send(r);
    });
  });
} );

// GET find :id
router.get( '/:id', function ( req, res ) {
  MongoClient.connect(url, { useNewUrlParser: true }, function(err, client) {
    let key = {}
    key[req.params.id] = { $regex:".*" }
    client.db('db').collection("restapi").findOne( key, function(err, r) {
      client.close();
      res.send(r);
    });
  });
} );

// POST insert data
router.post( '/', function ( req, res ) {
  MongoClient.connect(url, { useNewUrlParser: true }, function(err, client) {
    let obj = req.body;
    client.db('db').collection("restapi").insertOne(obj , function(err, r) {
      client.close();
      res.send(r);
    });
  });
});

// PUT update data
router.put( '/:id', function ( req, res ) {
  MongoClient.connect(url, { useNewUrlParser: true }, function(err, client) {
    let obj = req.body;
    let key = {}
    key[req.params.id] = { $regex:".*" }
    client.db('db').collection("restapi").findOneAndUpdate( key, {$set:obj}, {}, function(err, r) {
      client.close();
      res.send(r);
    });
  });
} );

// DELETE remove data
router.delete( '/:id', function ( req, res ) {
  MongoClient.connect(url, { useNewUrlParser: true }, function(err, client) {
    let key = {}
    key[req.params.id] = { $regex:".*" }
    client.db('db').collection("restapi").findOneAndDelete( key, function(err, r) {
      client.close();
      res.send(r);
    });
  });
} );

module.exports = router;

ここで作ったdata.jsを使うようにメインのapp.jsも少しだけ書き換えます。

app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var dataRouter = require('./routes/data'); // ★これを追加★

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/data', dataRouter); // ★これを追加★

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

※ 最初にはいってた Users は消しちゃってますが残っててもいいです

テスト

これで動く環境は整ったので実行。

PORT=8080 npm start

クライアント側のシェルなどから適当にコマンドをうってみます。

$ curl http://xxxx:8080/data
[]

最初は空です。
データを2つくらい追加してみます。

$ curl http://xxxx:8080/data -X POST -d "name=mio"
{"result":{"n":1,"ok":1},"connection":{"id":3,"host":"localhost","port":27017},"ops":[{"name":"mio","_id":"5cfa406159b3531cf05214f6"}],"insertedCount":1,"insertedId":"5cfa406159b3531cf05214f6","n":1,"ok":1}

$ curl http://xxxx:8080/data -X POST -d "milk=coffee"
{"result":{"n":1,"ok":1},"connection":{"id":5,"host":"localhost","port":27017},"ops":[{"milk":"coffee","_id":"5cfa40b459b3531cf05214f7"}],"insertedCount":1,"insertedId":"5cfa40b459b3531cf05214f7","n":1,"ok":1}

追加されたっぽいので確認してみます。

$ curl http://xxxx:8080/data/name
{"_id":"5cfa406159b3531cf05214f6","name":"mio"}

$ curl http://xxxx:8080/data/milk
{"_id":"5cfa40b459b3531cf05214f7","milk":"coffee"}

更新してみます。

$ curl http://xxxx:8080/data/name -X PUT -d "name=miomio"

$ curl http://xxxx:8080/data/name
{"_id":"5cfa406159b3531cf05214f6","name":"miomio"}

削除も。

$ curl http://xxxx:8080/data/name -X DELETE

とりあえずこんな感じ。

あとはこれを Vue.js などのフロントからgetでもpostでも何でもうまいこと扱ってあげたら色々簡単にためすにはよいと思います。

謝辞

こちらのQiitaからインスピレーションいただきました。多謝。
https://qiita.com/itagakishintaro/items/a1519998a91061cbfb1e

2
4
1

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
2
4