実行環境は以下のとおり。
- Windows7
- Node.js >= 6.0
- Express - 4.14.0
- Node.js用のWebフレームワーク
- body-parser - 1.15.2
- POSTでボディパラメータを受け取るため
- Sequelize - 3.27.0
- PromiseベースのORMライブラリ
- pg - 6.1.0
- PostgreSQLのNode.js用クライアント
- PostgreSQL - 9.4.7
- さくらのクラウド データベースアプライアンス(プレビュー版)
DBサーバ(PostgreSQL)を用意する
今回はイチからDB環境を用意するのが面倒だったので、さくらのクラウドのデータベースアプライアンスを使った。現在はプレビュー版で無料で利用できるので、ありがたく使わせていただいた。
ローカルやサーバのセットアップが不要なので、さっと使いたいときに便利!
RESTful APIサーバをつくる
DBサーバとは別に、RESTful APIサーバ(APサーバ)をつくる。
ディレクトリ構成は以下のとおり。
. ├─ app.js ├─ config.json ├─ package.json ├─models │ ├─ index.js │ └─ user.js └─routes └─ user.js
app.jsがメイン。
models配下が、データベース関連。index.jsにSequelizeの定義、user.jsにテーブルの定義が書かれている。
routes配下が、RESTful APIのエンドポイントごとにまとめられている。
設定ファイル
// config.json
{
"hostname": "IPアドレス/ホスト名",
"database": "develop(データベース名)",
"username": "develop(ユーザ名)",
"password": "********(パスワード)"
}
今回はさくらのクラウドのデータベースアプライアンスを使っているので、hostnameはアプライアンスのIPアドレス、databaseとusernameはデフォルトユーザ名、passwordは設定したパスワードを指定する。package.json
// package.json
{
"name": "node-postgres-sample",
"dependencies": {
"body-parser": "^1.15.2",
"express": "^4.14.0",
"pg": "^6.1.0",
"sequelize": "^3.27.0"
}
}
Modelsの定義
データベースのModelsを定義する。まずはメインとなるmodels/index.js。内容的には、設定が書かれたconfig.jsonを読み込んでコネクションの定義を行い、次にmodels配下のjsファイルを読み込む。
// ./models/index.js
const Sequelize = require('sequelize');
const config = require('../config.json');
const fs = require('fs');
const path = require('path');
const sequelize = new Sequelize(
config.database,
config.username,
config.password,
{
host: config.hostname,
dialect: 'postgres'
}
);
const db = {};
// models配下のjsファイルを読み込む
fs.readdirSync(__dirname)
.filter(file => file.indexOf('.js') && file !== 'index.js')
.forEach(file => {
const model = sequelize.import(path.join(__dirname, file));
db[model.name] = model;
});
// 今回はassociateの定義をしないので実行されない
Object.keys(db).forEach(modelName => {
if ('associate' in db[modelName]) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
次にModelsの定義をする。
Userというテーブル名で、フィールドはusernameとemailだけという簡単な定義。
// ./models/user.js
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
username: DataTypes.STRING,
email: DataTypes.STRING
});
return User;
};
RESTful APIのエンドポイントの定義
// ./routes/user.js
const models = require('../models');
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
models.User.findAll().then(result => {
if (result && result.length > 0) {
res.json(result);
} else {
res.status(204);
res.send();
}
}).catch(err => {
res.status(409);
res.json(err);
});
});
router.get('/:id', (req, res) => {
models.User.findOne({
where: {
id: req.params.id
}
}).then(result => {
if (result) {
res.json(result);
} else {
res.status(204);
res.send();
}
}).catch(err => {
res.status(409);
res.json(err);
});
});
router.post('/', (req, res) => {
models.User.create({
username: req.body.username,
email: req.body.email
}).then(result => {
res.status(201);
res.send(result);
}).catch(err => {
res.status(409);
res.send(err);
});
});
router.put('/:id', (req, res) => {
models.User.update({
username: req.body.username,
email: req.body.email
}, {
where: {
id: req.params.id
}
}).then(result => {
res.status(204);
res.json(result);
}).catch(err => {
res.status(409);
res.json(err);
});
});
router.delete('/:id', (req, res) => {
models.User.destroy({
where: {
id: req.params.id
}
}).then(result=> {
res.status(204);
res.json(result);
}).catch(err => {
res.status(409);
res.json(err);
});
});
module.exports = router;
エントリーポイント
// ./app.js
const http = require('http');
const express = require('express');
const bodyParser = require('body-parser');
const port = process.env.PORT || 3000;
const models = require('./models');
const user = require('./routes/user');
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
const router = express.Router();
router.use('/user', user);
app.use('/api', router);
models.sequelize.sync().then(() => {
http.createServer(app).listen(port);
console.log('listening');
});
ちなみに、APIのテストはPostmanというChromeアプリを使うと便利。
ただChromeアプリが2018年までに段階的に終了になると発表されたので、おそらく2017年上半期にはPostmanもインストールできなくなり、2018年には使えなくなるかもしれないので注意。
Sequelizeの詳しい使い方は、以下の記事を参考にしてほしい。
本番で運用する場合は、これらに加え、pm2というプロセス管理のモジュールを使ったり、log4jsとかでロギングしたり、エラー処理をもうちょっとなんとかしたり、と改善点はいくつもあるが、今回はここまで。
参考サイト
- Sequelize | The Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL
- Express でのルーティング
- HTTP Status Codes
以上
written by @bc_rikko
0 件のコメント :
コメントを投稿