世界で最も広く使用されているNode.jsフレームワークであるExpressは、開発者によるJavaScriptバックエンドウェブサーバーの構築を後押しする優れものです。このフレームワークには、バックエンド開発者が必要とするあらゆる機能が組み込まれており、ルーティングとウェブリクエストへの応答が簡単に設定できます。

Express.jsについて知っておくべきことについてはすでにまとめてありますので、こちらの記事ではより実践的な使い方をご紹介します。Express.jsを使用してNode.jsアプリのサンプルを作成し、デプロイする方法を見ていきましょう。

Express.jsで素早くアプリを開発する

今回の記事では、エンドポイントへのリクエストを受け取り、リクエストのパラメータを使用してデータベースを呼び出し、データベースから JSON として情報を返すウェブアプリケーションの構築方法をご紹介します。

前提条件

この説明を読み進めるには、以下のものがPCにインストールされている必要があります。

  • Node.jsNode Package Manager(npm)─JavaScriptに不可欠な実行環境とパッケージマネージャー
  • Git─共同ソフトウェア開発を促進する分散バージョン管理システム

Expressアプリケーションジェネレーター

Express.jsについての説明にあるプロセスを使用して、既存のNodeアプリケーションにExpressを追加できますが、ゼロから始める場合は、Expressジェネレーターというさらに簡単な方法もあります。

Express.jsの公式Expressジェネレーターは、言うなればアプリケーションのスケルトンを生成できるNodeパッケージです。アプリケーションのフォルダを作成し、npxコマンド(Node.js 8.2.0で利用可能)を実行します。

mkdir express-application
npx express-generator

生成が完了すると、ターミナルに、作成されたフォルダ/ファイルの一覧と、依存関係をインストールしてアプリケーションを実行するためのコマンドが表示されます。以下のコマンドを実行して、依存関係をインストールします。

npm install

次に、ウェブサーバーを起動します。

DEBUG=myapp:* npm start

スケルトンアプリケーションには、基本的なホームページをレンダリングするインデックスルートがあらかじめ組み込まれています。これをブラウザで見るには、localhost:3000にアクセスしてみてください。

スケルトンExpressアプリケーションを理解する

お好みのコードエディタでExpressアプリケーションを開くと、ウェブアプリケーションの骨格となる基本構造が確認できます。

/
|-- /node_modules
|-- /public
|-- /routes
    |-- index.js
    |-- users.js
|-- /views
    |-- error.jade
    |-- index.jade
    |-- layout.jade
|-- app.js
|-- package.json
  • node_modules:このディレクトリがプロジェクトにインストールされたすべての依存関係とライブラリを保存します。
  • public:CSS、JavaScript、画像などの静的アセットが格納されます。これらのファイルはクライアントのブラウザに直接配信されます。
  • routes:様々なルートを定義し、各URLからのリクエストを処理するファイルがここに保存されます。
  • views:サーバーがユーザーインターフェースを作成するためにレンダリングするテンプレートやビューが格納されます。この例で言えば、error.jadeindex.jadelayout.jadeは、Jadeテンプレート言語で記述されたテンプレートです。これらは、動的なコンテンツを構造化し、ユーザーにレンダリングする役割を果たします。
  • app.js:このファイルは通常、Expressアプリケーションのエントリーポイントとして機能します。サーバーの設定、ミドルウェアのセットアップ、ルートの定義、リクエストとレスポンスの処理が行われます。
  • package.json:このファイルには、アプリケーションに関するメタデータが含まれます。依存関係やプロジェクト構成の管理に有用です。

ルート処理について理解する

Expressアプリケーションでは、routesディレクトリにルートが個別のファイルとして定義されます。プライマリルートは、しばしばインデックスルートと呼ばれ、routes/index.jsファイルに存在します。

このインデックスルートがGETリクエストを処理し、フレームワークによってHTMLで生成されたウェブページを用いることで応答します。以下は、GETリクエストがどのように処理され、基本的なウェルカムページがレンダリングされるかを示したコードです。

var express = require('express');
var router = express.Router();

/* ホームページを取得/GET */
router.get('/', function(req, res, next) {
 res.render('index', { title: 'Express' });
});

module.exports = router;

このres.render()関数をres.send()に変更すると、レスポンスタイプがHTMLからJSONに変わります。

var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
  res.send({ key: 'value' });
});

module.exports = router;

この機能を拡張すると、同じファイルに別のルートを追加し、パラメータを受け入れる新しいエンドポイントを導入できます。次のコードは、アプリケーションが別のエンドポイントでトラフィックを処理し、パラメータを抽出して、その値についてJSONで応答する例です。

/* 新しいリソースを取得/GET */
router.get('/newEndpoint', function(req, res, next) {
  res.send({ yourParam: req.query.someParam });
});

localhost:3000/newEndpoint?someParam=whateverGETリクエストを送信すると、文字列 “whatever”を含むJSONの出力が得られます。

GETリクエスト─Postmanを使ってローカルでアプリケーションを実行
GETリクエスト─Postmanを使ってローカルで実行してみる

ExpressとKinstaアプリケーションホスティング

自分のPC内でウェブリクエストを行うのは簡単ですが、ウェブ開発はローカルホストから離れてからが本番です。Kinstaを使うことで、データベースが必要な場合であっても、ウェブへのアプリケーションのデプロイを簡単に行うことができます。

それでは、データベース機能を統合し、アプリケーションとデータベースの両方をウェブにデプロイすることで、アプリケーションの機能を拡張し、どのコンピュータからでもアクセスできるようにしましょう。

KinstaのアプリケーションホスティングにExpressアプリケーションをデプロイする前に、アプリケーションのコードとファイルを選択したGitサービス(BitbucketGitHub、またはGitLab)にプッシュする必要があります。アプリケーションのルートディレクトリに.gitignoreファイルを作成し、  そこでnode_modules を扱うようにします。これにより特定のファイルをGitサービスにプッシュせずに済みます。

リポジトリを設定したら、以下の手順に従って、ExpressアプリケーションをKinstaにデプロイしてください。

  1. ログインするか、アカウントを作成してMyKinstaを表示
  2. GitサービスでKinstaを認証する
  3. 左サイドバーの「アプリケーション」をクリックし、「アプリケーションの作成」をクリック
  4. デプロイしたいリポジトリとブランチを選択
  5. アプリに一意の名前を割り当て、「データセンターの所在地」を選択
  6. ビルド環境を設定(このデモでの推奨─「Standardビルドマシン」と「Nixpacksを使用してコンテナイメージを設定」を選択)
  7. すべてのデフォルト設定を使用し、お支払い情報などを入力した上で「今すぐデプロイする」をクリック

Kinstaは標準でExpressアプリケーションジェネレーターに対応しています。上記のステップを完了すると、アプリケーションで自動的にビルドとデプロイプロセスが始まります。

デプロイ画面には、アプリケーションのデプロイURLが表示されます。この記事の前のセクションで構築したエンドポイントをテストするために、/newEndpoint?someParam=whateverを追加することができます。

Expressアプリケーションにデータベースを追加する方法

あらゆるアプリケーションに、データベースが必要になります。Kinstaのフルマネージドデータベースサービスでは簡単にセットアップ可能です。

続いては、Kinstaでデータベースを作成する方法をご説明します。

  1. MyKinstaのサイドバーにある「データベース」セクションに移動します。
  2. 「データベースの作成」をクリックします。名前を入力し、データベースの種類を選択して、データベースの詳細を設定します。
  3. 「PostgreSQL」を選択します。すると以下のように「データベースのユーザー名と「データベースのパスワード」が自動で生成されます。

    The MyKinsta database configuration step of adding a new database
    データベースを追加する─MyKinstaでのデータベース構成

  4. Expressアプリケーションをホストしたのと同じ「データセンターの所在地」を選択し、希望のサイズを設定します。
  5. お支払い情報を確認し、「データベースを作成する」をクリックします。

データベースが正常に作成されたら、次のステップに進みます。

  1. データベースをクリックして、データベースの詳細にアクセスします。「概要」ページで、「内部接続」セクションに移動します。
  2. 該当するアプリケーションを選択します。
  3. 「アプリケーションへの環境変数の追加」にチェックを入れます。
  4. 接続を追加」をクリックして、作成したデータベースとアプリケーションを接続します。

次に、作成したデータベースの接続文字列をコピーして、データベースツールを介して接続します。SQL接続ツールであれば何でも構いませんが、ここではBeekeeperを使用します。アプリを開き、「Import from URL」をクリックして接続文字列を貼り付け「Import」をクリックします。これで、作成したばかりのKinstaでホストするデータベースでSQLを実行できるようになります。

次に、データベースツール経由でデータベースに対してSQLステートメントを実行し、単一のエントリを持つ基本的なテーブルを作成してみます。

CREATE TABLE "States"
( id integer CONSTRAINT states_pk PRIMARY KEY,
  state_name varchar(100),
  capital varchar(100),
  state_bird varchar(100),
  "createdAt" TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  "updatedAt" TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

INSERT INTO "States"
VALUES(1, 'ohio', 'columbus', 'cardinal');

以下のデータベースパッケージをプロジェクトに追加します。

npm install sequelize pg

sequelizeはNode.jsのORMで、pgはPostgreSQLクライアントとして機能し、Node.jsアプリケーションと PostgreSQLデータベース間のやり取りを可能にします。

次に、idパラメータを持つGETリクエストを受け付け、そのidに関連付けられたデータベースの情報を返すアプリケーションコードを記述します。そのためには、index.jsファイルに変更を加えます。

var express = require('express');
var router = express.Router();
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize(process.env.CONNECTION_URI, {
  dialect: 'postgres',
  protocol: 'postgres',
});

const State = sequelize.define('State', {
  // モデル属性をここで定義
  state_name: {
  type: DataTypes.STRING,
  allowNull: true,
  unique: false
  },
  capital: {
  type: DataTypes.STRING,
  allowNull: true,
  unique: false
  },
  state_bird: {
  type: DataTypes.STRING,
  allowNull: true,
  unique: false
  },
}, {
  // 他のモデルオプションをここに記述
});

async function connectToDB() {
  try {
  sequelize.authenticate().then(async () => {
  // await State.sync({ alter: true });
  })
  console.log('Connection has been established successfully.');
  } catch (error) {
  console.error('Unable to connect to the database:', error);
  }
}
connectToDB();

/* 新しいリソースを取得/GET  */
router.get('/state', async function(req, res, next) {
  const state = await State.findByPk(req.query.id);
  if (state) {
   res.send(state)
  } else {
   res.status(404).send("state not found");
  }
});


/* ホームページを取得/GET */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

/* 新しいリソースを取得/GET */
router.get('/newEndpoint', function(req, res, next) {
  res.send({ yourParam: req.query.someParam });
});

module.exports = router;

コードの変更内容をコミットし、Gitリポジトリにプッシュします。その後、Kinstaに手動で再デプロイするか、自動デプロイを待ちます。

これで、id=1/statesエンドポイントにクエリを実行すると、データベースから状態を受け取ることができます。

MyKinstaでホストするアプリケーションへのGETリクエスト
MyKinstaでホストするアプリケーションへのGETリクエスト

以上で完了です。プロジェクトのコード一式はGitHubでご確認ください。

まとめ

この記事では、Expressフレームワークを用いた簡単なNode.jsアプリケーションの作成とデプロイの方法をご紹介しました。Expressジェネレーターを使用すると、わずか数ステップでアプリケーションを構築できます。また、Kinstaのアプリケーションホスティングを使用することで、アプリケーションのデプロイ合理化が捗り、最小限のセットアップで作業が完了します。

Node.jsアプリケーション開発にうまくExpressフレームワークの多機能性と利便性を持ち込むことがポイントです。Kinstaと組み合わせれば、設定に時間を費やすことなく、ExpressとNode.jsのメリットをいかんなくプロジェクトに反映することができます。

Expressアプリケーションジェネレーターは活用していますか?アプリケーションの開発に利用した時の使い心地はいかがでしたでしょうか?以下のコメント欄でお聞かせください。

Jeremy Holcombe Kinsta

Kinstaのコンテンツ&マーケティングエディター、WordPress開発者、コンテンツライター。WordPress以外の趣味は、ビーチでのんびりすること、ゴルフ、映画。高身長が特徴。