やりたいこと
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で立ち上げてますがこの辺りはご自由に。。
とりあえずブラウザでアクセスしてみて確認。良く見慣れたこれが出ます。
OKです。
Ctrl+Cとかでサーバは止めておきます。
ExpressからmongoDBの操作のアプリを作る。
Expressのフォルダ(今回はsite
)にいる状態て mongodb
を扱うためのライブラリをインストール。
npm install mongodb
REST APIの本題である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
も少しだけ書き換えます。
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