Packagistにパッケージを公開してみた
転職してから一年四ヶ月ほど経った
すごく中途半端な時期ではあるけども、今までにやったことを記録しておく。
・Webアプリケーション開発に従事
PHPで、フレームワークにLaravelを使いアプリケーション開発を行っている。
一部ではPythonとNode.jsを使っている。
・Gitを使うようになった
それまでも個人で使ってはいたけれど、チームで使うようになった。いわゆるGithub Flow。ブランチを切り、コミットし、プッシュして、プルリクを出してレビューをしてもらい(他のメンバーのものはして)、マージしてデプロイ。
・AWSを使うようになった
サービスをすべてAWS上に構築しているため、AWSを使うようになった。
後述するサービス立ち上げ時には、EC2、Route53、S3、RDS、Lambda、SNS、SQS、ElasticTranscoderなど一通りの設定を経験できた。AWS聞いていたとおりすごく楽である。
---
ここまでは仕事の全体的な事項。ここから個別の案件等について。
---
・二つのサービスを担当
DAU10,000程度のサービス二つのサーバーサイド主担当をしている。
コードを書いたり(レビューは受けている)、時々アクセス集中が予想されるときに用意をしておいたり、運用チームと協議の上機能追加や削除、改善など。
・サービス立ち上げ
担当している二つのサービスのうちの一つは、もともと存在していたもう一つのサービスからフォークされたもので、その立ち上げ準備からサービスイン、運用までメインで行った|ている。
その他、
・RDSのMySQLからAuroraへの移行
・ストリーミングサーバ構築
・Jenkins導入(自動テスト、コードカバレッジや複雑度の測定)
・Sorryサーバ立てる
などをやった。
Node.js + PostgreSQLを使ってアプリケーションを作る(7) CRUD用APIを作る
目次
今回やること
手順
- 1, 必要なモジュールを追加する body-parserモジュールをインストールし、app.jsに読み込み用コードを追加します。
$ node install --save body-parser
const bodyParser = require('body-parser'); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true}));
$ mkdir controllers/api $ vim controllers/api/task.js
controllers/api/task.jsには以下のように記述します。
'use strict'; const Promise = require('bluebird'); const Task = require('../../models/task'); const TaskCollection = require('../../collections/taskCollection'); const getTask = function(req, res){ const id = req.params.id; Task.forge({id: id}) .fetch({columns: ['title', 'description', 'created_at', 'updated_at']}) .then(function (task){ res.json(task.toJSON()); }) .catch(function (error) { res.status(500).json({msg: error.message}); }); }; const getTasks = function(req, res) { TaskCollection.getList() .then(function (tasks){ res.json(tasks); }) .catch (function (error) { res.status(500).json({msg: error.message}); }); }; const postCreate = function(req, res) { new Task({ title : req.body.title, description: req.body.description, created_at : new Date().toISOString(), updated_at : new Date().toISOString() }) .save() .then(function (task){ res.json(task.id); }) .catch (function(error){ res.status(500).json({msg: error.message}); }); }; const deleteDestroy = function(req, res) { new Task() .where('id', req.params.id) .destroy() .then(function (task){ res.json({message: 'success'}); }) .catch (function (error) { res.status(500).json({msg: error.message}); }); } module.exports = { getTask : getTask, getTasks : getTasks, postCreate : postCreate, deleteDestroy: deleteDestroy };
$ mkdir routes/api $ vim routes/api/task.js
routes/api/task.jsには以下のように記述します。
'use strict'; const express = require('express'); const router = express.Router(); const controller = require('../../controllers/api/task'); router.route('/') .get(controller.getTasks); router.route('/:id') .get(controller.getTask); router.route('/') .post(controller.postCreate); router.route('/:id') .delete(controller.deleteDestroy); module.exports = router;
その後、app.jsにroutes/api/task.jsを利用するようコードを追加します。
const api_task = require('./routes/api/task'); app.use('/api/tasks', api_task);
これで、CRUD用APIが作成できました。 GET http://localhost:3000/api/tasks/ ->task一覧を取得 GET http://localhost:3000/api/tasks/id ->特定のidのtaskを取得 POST http://localhost:3000/api/tasks/ ->taskを作成 DELETE https://localhost:3000/api/tasks/id ->特定のidのtaskを削除
ここまでのコードは
こちらに公開してあります。
Node.js + PostgreSQLを使ってアプリケーションを作る(6) ORMを利用する
目次
6, ORMを利用する <-今回
今回やること
Bookshelf.js (ORM)を利用して、データを表示する
手順
- 1, テスト用のデータをpsqlを利用して登録する
$ psql --username=nodeuser --password --dbname=nodeuser nodeuser=> INSERT INTO tasks(title, description, created_at, updated_at) VALUES('test', 'test task', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP); nodeuser=> ¥q
- 2, モデルを作成する modelsディレクトリを作成し、そこにTaskモデルを追加します。
$ mkdir models $ vim models/task.js
models/task.jsには以下のように記述します。
'use strict'; const Bookshelf = require('../bookshelf'); const Promise = require('bluebird'); const Task = Bookshelf.Model.extend({ tableName: 'tasks' }, { }); module.exports = Task;
- 3, コレクションを作成する collectionsディレクトリを作成し、そこにTaskコレクションを作成します。
$ mkdir collections $ vim collections/taskCollection.js
collections/taskCollection.jsには以下のように記述します。
const Bookshelf = require('../bookshelf'); const Task = require('../models/task'); const Promise = require('bluebird'); const TaskCollection = Bookshelf.Collection.extend({ model: Task, }, { getList: function(){ return new this() .fetch() .then (function (collection){ return collection.toJSON(); }) .catch (function (error){ throw error ; }); } }); module.exports = TaskCollection;
- 4, コレクションを利用する controllers/public/index.jsを以下のように書き換えます。
'use strict'; const Promise = require('bluebird'); const TaskCollection = require('../../collections/taskCollection'); const getIndex = function(req, res) { TaskCollection.getList() .then(function (tasks) { res.json(tasks); }) .catch (function (error) { res.status(500).json({msg: error.message}); }); }; module.exports = { getIndex: getIndex };
この状態でhttp://localhost:3000にアクセスすると、以下のようにtasksの内容が表示されます
[{"id":1,"title":"test","description":"test task","created_at":"2017-01-15T09:32:10.123Z","updated_at":"2017-01-15T09:32:10.123Z"}]
ここまでのコードは
こちらに公開してあります。
Node.js + PostgreSQLを使ってアプリケーションを作る(5) データベースを使用する
目次
5, データベースを使用する <-今回
今回やること
RDBMS(今回はPostgreSQL)をインストールし、Node.jsからそれにアクセスして使用できるようにする
手順
- 1, PostgreSQLのインストール
# apt-get install postgresql postgresql-contrib $ /etc/init.d/postgresql start
- 2, PostgreSQLにユーザーとデータベースを追加
$ sudo su postgres $ psql
psqlはPostgreSQLのターミナル型フロントエンドです。これを使ってアプリケーション用のPostgreSQLユーザー、データベースを作成します。
postgres=# CREATE ROLE nodeuser LOGIN CREATEDB PASSWORD 'nodeuser'; postgres=# CREATE DATABASE nodeuser owner nodeuser; postgres=# ¥q $ exit
- 3, Node.jsにデータベースアクセス用のモジュールを追加 nodeuserにユーザーを切り替え、データベースアクセス用モジュールを追加します。
Expressのドキュメントには、pg-promiseを使用すると書かれているのですが、 クエリ文字列を自分で組み立てなくてはいけないなど辛い部分が多いので、次のモジュールを使用します。
・Knex.js - A SQL Query Builder for Javascript
$ npm install --save pg $ npm install --save knex $ npm install -g knex // knexはコマンドで使用するのでグローバルインストールする $ npm install --save bookshelf
- 4, データベース接続設定を追加
$ knex init
これでknexfile.jsができるので、以下のように記述します。
// Update with your config settings. module.exports = { development: { client: 'postgresql', connection: { database: 'nodeuser', user: 'nodeuser', password: 'nodeuser' }, pool: { min: 2, max: 10 }, migrations: { tableName: 'migrations' } }, production: { client: 'postgresql', connection: { database: 'my_db', user: 'username', password: 'password' }, pool: { min: 2, max: 10 }, migrations: { tableName: 'knex_migrations' } } };
また、bookshelf.jsを作成し、以下のように記述します。
const config = require('./config')(process.env.ENV) const knexconfig = require('./knexfile'); const knex = require('knex')(knexconfig[config.env]); const bookshelf = require('bookshelf')(knex); module.exports = bookshelf;
$ mkdir migrations $ knex migrate:make create_tasks
これでmigrationsディレクトリ内にマイグレーションファイルが作成されます。 作成されたマイグレーションファイルに、以下のように記述します。
exports.up = function(knex, Promise) { return Promise.all([ knex.schema.createTable('tasks', function(table){ table.increments('id').primary(); table.string('title'); table.string('description'); table.timestamps(); }) ]) }; exports.down = function(knex, Promise) { return Promise.all([ knex.schema.dropTable('tasks') ]) };
マイグレーションファイルを作成したら、
$ knex migrate:latest
を実行し、データベースに反映します。 psqlでデータベースの状態を確認すると、テーブルが作成されていることがわかります。
$ psql --username=nodeuser --password --dbname=nodeuser; nodeuser=> \dt; List of relations Schema | Name | Type | Owner --------+-----------------+-------+---------- public | migrations | table | nodeuser public | migrations_lock | table | nodeuser public | tasks | table | nodeuser (3 rows)
ここまでのコードは
に公開してあります。
Node.js + PostgreSQLを使ってアプリケーションを作る(4) ルーティング、コントローラーの追加
目次
4, ルーティング、コントローラーの追加 <-今回
今回やること
app.jsからルーティングとコントローラーを別ファイルに分割する
手順
- 1, コントローラーを作成
$ mkdir controllers $ mkdir controllers/public $ vim controllers/public/index.js
controllers/public/index.jsに、以下のように記述します。
'use strict'; const getIndex = function(req, res) { res.send('Hello World!'); }; module.exports = { getIndex: getIndex };
これで、モジュールとしてコントローラーを登録し、他の場所から呼び出せるようになります。
- 2, ルーティングの作成
$ mkdir routes $ mkdir routes/public $ vim routes/public/index.js
routes/public/index.jsに、以下のように記述します。
'use strict'; const express = require('express'); const router = express.Router(); const controller = require('../../controllers/public/index'); router.route('/') .get(controller.getIndex); module.exports = router;
'/'のURLが呼ばれた場合、1で作成したコントローラーのgetIndexで処理するように紐付けています。
- 3, ルーティングを使用するようにapp.jsを変更 app.jsを以下のように書き換える
var express = require('express'); var app = express(); // config const config = require('./config')(process.env.ENV); // routing const public_index = require('./routes/public/index'); app.use('/', public_index); app.listen(config.port, function () { console.log('Example app listening on port ' + config.port); });
'/'のURLが呼ばれた場合、2で作成したルーティング設定を適用するよう設定しています。
この状態で
$ ./node_modules/node-dev/bin/node-dev app.js
でアプリケーションを開始し、curl htttp://localhost:3000 とすると、
Hello World!
と表示されます。
ここまでのコードは
に公開してあります。
Node.js + PostgreSQLを使ってアプリケーションを作る(3) 設定ファイルの追加
目次
3, 設定ファイルの追加 <-今回
今回やること
設定ファイルを追加し、環境によって設定を切り替えられるようにする
手順
-1, アプリケーションディレクトリにconfigディレクトリを追加し、その中にindex.jsを追加する
$ mkdir config $ touch config/index.js
-2, config/index.jsを以下のように編集する
'use strict'; const common_config = {}; const config = { development: { env: 'development', port: 3000, common: common_config }, production: { env: 'production', port: 3000, common: common_config }, }; module.exports = function(env) { return config[env || process.argv[2] || 'development']; };
config/index.jsでは、設定オブジェクトを返す関数をモジュールとして登録しています。 別の箇所からrequireで呼び出し、引数に環境名を与えることで、それぞれの環境に応じた設定を使う事ができます。
-3, app.jsを設定ファイルを使うように変更する
app.jsを以下のように書き換えます。
var express = require('express'); var app = express(); // config const config = require('./config')(process.env.ENV); app.get('/', function (req, res) { res.send('Hello World!'); }); app.listen(config.port, function () { console.log('Example app listening on port ' + config.port); });
config/index.jsで、 const config = require('./config')(process.env.ENV); を追加し、設定モジュールを呼び出しています。 このとき環境変数にENVを登録すればそれに応じた設定が返ってきます。また、ENVが登録されていない場合はdevelopmentの設定を返すようにconfig/index.jsでしてあります。現在は開発環境で作業を行っていますので、特に環境変数を登録しません。 この状態で
$ ./node_modules/node-dev/bin/node-dev app.js
でアプリケーションを開始すると、
Example app listening on port 3000
と表示されます。
ここまでのコードは
に公開してあります。