20190710のNode.jsに関する記事は7件です。

Node.jsでSlack連携される問い合わせフォーム作ってみた

はじめに

今回Node.jsの勉強の一環で、問い合わせフォームを作成しましたのでその流れをまとめます。
また、問い合わせされたらメールが飛ぶのではなく、Slackに連携されるようにしました。

入力画面.png

Slack_-_えすぷりてっく_Tokyo.png

環境構築

環境構築は、様々な記事を参考に、下記の流れで行いました。

(Xcodeをインストール)

1.node.js管理ツール(nvs)をインストール

2.nvsを使ってnode.jsをインストール

3.npmをインストール

「便利なパッケージ管理ツール!npmとは【初心者向け】」
https://techacademy.jp/magazine/16105

↑こんな感じの流れで、node.jsがローカルで使えるようになりました。

そして、今回はnode.jsのフレームワーク「Express」を使います。

npm install express

また、「ejs」というテンプレートエンジンを使います。

express -e myapp

(-e:ejs、myapp:任意の名前)

実装

全体の流れとして、入力画面 → 確認画面 → 完了画面 → Slackに送信 という流れになります。

そのため、入力画面、確認画面、完了画面の3つのビューを作成する必要があります。

view
┗ ━ index.ejs
┗ ━ confirm.ejs
┗ ━ result.ejs

入力画面

まず、入力画面では、formタグを記述します。
action="/confirm" と書くことで、formがsubmitされたらconfirm画面に遷移するようにします。

index.ejs
<form action="/confirm" method="POST" name="contact">

  <input type="text" name="name" value="" required>
  <!-- 必要なinputタグなどを記述する -->
 <input type="submit" name="submit" value="入力内容の確認">

</form>

確認画面

そして、入力内容の確認ボタンを押されたら(submitされたら)、/confirm画面に遷移されます。
その時の動きを routes/index.js に描いてあげます。

index.js
/* POST : /confirm */
router.post('/confirm', function(req, res){

  res.render('./confirm.ejs', { 
    name: req.body.name
  });

});

router.post('/confirm', function(req, res){
→/confirm にPOSTされてきたら実行される(入力画面のフォームがsubmitされたら)

res.render('./confirm.ejs', {
→views/confirm.ejs を返す、表示する

name: req.body.name
confirm.ejs に変数を渡す
nameという名前の変数に「req.body.name」(formの<input type="text" name="name">に入力された値)を入れて渡す
なので、受け取る時は<%= name %>

confirm.ejs
<form action="/result" method="POST" name="contact">
 <%= name %>
 <input type="submit" name="submit" value="送信">
</form>

<%= name %>と書けば、入力画面で入力された値が表示されます。

完了画面

そして、入力内容の確認ボタンを押されたら(submitされたら)、/result画面に遷移されます。
確認画面の時と同じく、その時の動きを routes/index.js に描いてあげます。

index.js
router.post('/result', function(req, res){

  var request = require("request")

  // slack連携
  request.post('https://slack.com/api/chat.postMessage', {
      form: {
          token: 'トークンを書く', // slackのトークン
          channel: 'test', // slackのチャンネル名
          username: '問い合わせ', // slackに投稿される名前
          text: // slackに投稿される内容
          '```名前:' + formdata.name + '```'
      }
  }, function (error, response, body) {
      console.log(error)
  })

  res.render('./result.ejs', { title: '完了画面' });

});

ちなみに、slackのトークン発行は、こちらからログインして create taken で発行できます。

また、requestモジュールをインストールする必要があります。

npm install request

Slack連携のテストするところ
https://api.slack.com/methods/chat.postMessage

完成!

こんな感じの流れで、問い合わせフォームが作成できました。
何かの参考になれば幸いです。
ちなみにSlackのトークンは環境変数に入れて管理するなどして、GithubやHerokuなどにあげないように気をつけましょう!

参考:Node.jsでの環境変数の使い方:モジュール「dotenv」
https://numb86-tech.hatenablog.com/entry/2017/01/24/000940

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

はじめよう Express 第1回

OTA TECH BLOGで公開している記事です。

第1回

1 Expressとは
2 セットアップ
3 Expressの構造
4 ルーティング

第2回

5 データベース

第3回

6 MVCアーキテクチャー

--- 以降は準備中です ---
第4回以降

7 Request、Response オブジェクト
8 Vue.jsと連携
9 cookie
10 session
11 環境変数の利用
12 エラーハンドリング
13 セキュリティ
14 HTTPS
15 プロセスマネージャー (PM2)

1. Expressとは

ExpressはNode.js上で稼働するサーバーサイドのWEBアプリケーションフレームワークです。公式サイトの言葉を借りると、ExpressはFast(高速)で、Unopinionated(自説に固執しない)で、Minimalist(ミニマリスト)な、Node.js用Webフレームワークです。

Screen Shot 2019-06-20 at 22.09.17.png
https://expressjs.com/

この言葉にあるように、ExpressはNodeの特徴でもある高速性を重視しているため、Express本体は最小限で最軽量な構成になっています。ORM(DBのインターフェース)もなければ、テンプレートエンジンもない状態です。これらの機能に関しては必要に応じてパッケージを加えていくことになりますが、「どのような構成がよいか?」ということに関してExpressのスタンスはUnopinionatedなので、そこはプログラマの意思に委ねられているというわけです。このようなExpressの設計思想は、下図のようにRuby on RailsやLaravelと比較すると解りやすいかもしれません。

Screen Shot 2019-06-20 at 23.12.16.png

2018年にNode.js Foundationが行ったユーザー調査「2018 Node.js User Survey Report」では、Expressが人気フレームワークの1位になっています。

Screen Shot 2019-06-24 at 17.24.50.png

https://nodejs.org/en/user-survey-report#Tools-Technologies-Used

1.1 Express ジェネレータとは

express-generatorはアプリケーション・スケルトンを作成するためのツールです。スケルトンは、他のフレームワークではScaffold(足場)とよばれることもあります。
express-generatorは、npm パッケージとしてExpress本体とは別にインストールします。

1.2 今回作成するもの

第1回〜3回のレッスンでは、Expressジェネレータを使ったWEBアプリの実装方法をざっくり把握することを目的とし、「データベースに保存されたユーザーのリストを画面に表示する」という機能を作成します。この機能に特に実用性はありませんが、以下のようなポイントを把握できると思います。

  • express-generator (スケルトン生成)
  • ルーティング
  • MVC (Model View Controller)
  • ORM (Object-Rerational Mapping)
  • RDB (Rerational Database)
  • テンプレートエンジン

2 セットアップ

ExpressのHello Worldには2段階あります。

1つ目は、Express ジェネレータを使わないで素のExpressだけで表示するHello Worldです。この実装方法に関しては、公式ページに解りやすいマニュアルがありまし、スキップすることもできるので、ここでは特に触れないことにします。
https://expressjs.com/ja/starter/installing.html
https://expressjs.com/ja/starter/hello-world.html

2つ目は、Express ジェネレータでスケルトンを作成して表示するHello Worldです。
今回はここから進めていきます。

2.1 Express ジェネレータをインストールする

nodeはインストール済みという前提で、Expressジェネレータのインストールから始めます。以下のコマンドを実行してexpress-generatorをインストールします。

$ npm install express-generator -g

インストールが成功したことを確認するために、ヘルプ情報を表示してみます。

$ express -h

ヘルプ情報が表示されれば成功です。

2.2 スケルトンを生成

それではスケルトンを作成します。(スケルトンはScaffold(足場)と呼ばれることもあります。)スケルトンの作成にはexpressコマンドを使います。コマンドの引数に、テンプレートエンジンの種類と、アプリケーション名を指定します。

$ express --view=[テンプレートエンジンの種類] [アプリケーション名]

今回はテンプレートエンジンにEJSを使うことにし、アプリケーション名を「myapp」にします。

$ express --view=ejs myapp

コマンドを実行すると、下図のようなスケルトンが生成されます。

スクリーンショット 2019-06-11 19.40.57.png

モジュールの依存情報がpackage.jsonに定義されていますので、モジュールをインストールしましょう。

2.3 Nodeモジュールをインストールする

次のコマンドを実行してモジュールをインストールします。

$ cd myapp
$ npm install

コマンドを実行するとnode_modulesディレクトリにモジュールがインストールされ、以下のようなフォルダ構成になります。

スクリーンショット 2019-06-11 19.44.55.png

2.4 アプリを起動してみる

$ npm start

ブラウザで以下のURLを開いてみましょう。

http://localhost:3000/

ExpressのWelcome画面が表示されれば成功です。

Screen Shot 2019-06-21 at 15.13.23.png

スケルトンにはもうひとつ/users/というページが存在しています。この後のレッスンで使いますので、以下のURLも開いてみましょう。

http://localhost:3000/users/

respond with a resourceという文字が表示されれば成功です。

Screen Shot 2019-06-25 at 12.01.50.png

確認ができたらCtrl+cで終了しておきましょう。

3. Expressの構造

3.1 スケルトンの初期状態

Expressジェネレータが生成したスケルトンは、下図のような構造で動作しています。

Screen Shot 2019-06-25 at 10.41.37.png

  • HTTPリクエストを3000番ポートでListenします。
  • HTTPリクエストの情報は、reqという名前のオブジェクトにセットされます。
  • ルーティング機能が、URLのパスに応じて、処理のルートを振り分けます。
  • TOPページの表示には、Viewエンジン(今回はEJS)が使われています。
  • 静的ファイルへのリクエストは、/publicフォルダにルーティングされます。
  • HTTPレスポンスは、resという名前のオブジェクトを使って返します。

この先は、このスケルトンを出発点として、いろいろな機能を肉付けしていくことになります。

3.2 アプリ起動からルーティングまでの流れ

アプリの起動からルーティング処理までの流れを見てみます。ターミナルから起動コマンド$ npm startを実行すると、package.jsonのstartに登録されているnode ./bin/wwwが実行されます。

package.json
...
"scripts": {
    "start": "node ./bin/www"
  },
...

/bin/wwwはHTTPサーバーを実行し、メインスクリプトのapp.jsと結びつけます。その後は、HTTPリクエストが発生する度に、URLのパスに対応したルーティングのハンドラが実行されます。

Screen Shot 2019-06-24 at 13.49.03.png

Expressでページを追加するときは、そのページのルーティングを設定し、ページの機能やビューと結びつけるといううことを行っていきます。

4. ルーティング

4.1 ルーティングとは

Expressアプリは、HTTPリクエストを受けとってレスポンスを返します。ルーティングとは、受け取ったURLのパスに対して、アプリでどんな処理をするのかという処理の流れを実装することです。例えば、エンドユーザーがアプリケーションに対して、http://localhost/users/というURLでアクセスしたとします。そのとき、/users/というパスに対してどのようなレスポンスを返すのか、アプリケーションで実装します。

Screen Shot 2019-06-21 at 7.26.23.png

Node.jsでWebアプリを作るのが初めての方にとっては、ルーティングを実装するという感覚が新鮮かもしれません。Node.js以外の言語を使う場合、ルーティング処理はApacheなどのWebサーバーが担当します。

Screen Shot 2019-06-21 at 7.40.26.png

また、Apacheなどの場合は、URLのパスとドキュメントルート以下の物理ファイルのパスは密接に関係していますが、Node.jsの場合は物理ファイルのパスを対応させることも、対応させないこともどちらも可能です。

Screen Shot 2019-06-21 at 8.14.54.png

Expressジェネレータが生成するスケルトンでは、静的なファイルに関してはpublicフォルダ以下に対応付けされており、プログラマが意識しなくても自動的にルーティングされます。動的な処理をするパスに関しては、プログラマがコードでルーティング処理を実装します。動的なルーティングの実装は、主にroutesディレクトリ以下に配置していきます。

Screen Shot 2019-06-21 at 8.58.28.png

4.2 静的ページのルーティング

静的ファイルに関しては/public/フォルダに割り当てられていますので、ここに簡単なHTMLページを配置してみます。ファイル名をhello.htmlとします。

Screen Shot 2019-06-26 at 8.59.36.png

hello.html
<!DOCTYPE html>
<html>
    <head>
        <title>Hello</title>
    </head>
    <body>
        <h2>Hello!</h2>
    </body>
</html>

アプリを起動して表示してみます。

$ npm start

ブラウザで以下のURLを開きます。

http://localhost:3000/hello.html

Hello!が表示されれば成功です。

Ctrl+cでアプリを終了します。

Screen Shot 2019-06-26 at 9.10.17.png

4.2 ルーティングを実装する

それでは動的なページに関して、実際にどのようにルーティングを実装するのか見ていきましょう。ルーティングは、URLのパスに対するハンドラfunctionという形で実装します。例えば http://localhost/users/ というURLに対するルーティングは、/users/ というパスと、それに対応するハンドラ function を対応させるように書きます。

スクリーンショット 2019-06-16 12.50.08.png

4.3 ルーティングの実装方法

ルーティングの定義

app.METHOD(PATH, HANDLER)
  • app : express のインスタンス
  • METHOD : get/post など
  • PATH : URLのパス部分
  • HANDLER : パスが一致したときに実行されるfunction

ルーティングの実装方法には、app.jsに直接書く方法と、モジュール化する方法の2種類あります。

(1) app.jsに直接書く方法
app.js
var express = require('express');
var app = express();
....
app.get('/', function (req, res) {
  res.send('Hello World!');
});

このようにapp.jsに直接ルーティングを書くことができるのですが、ルーティングが増えるにしたがって、app.jsのコードが肥大化してしまうという問題が起こります。そこで、次のようにルーティング機能をモジュール化する方法がサポートされています。

(2) モジュール化する方法

Express Routerという機能を使ってハンドラの部分を別ファイルに切り出すことができます。

Screen Shot 2019-06-21 at 12.51.37.png

Expressジェネレータが生成したスケルトンには、./routes/user.jsというファイルがあり、このような内容になっています。

./router/user.js
var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

module.exports = router;

app.js側では、外出しにしたルータモジュール(users.js)をrequireしておき、リクエストURLの'/user'というパスに対応づけられています。

./app.js
var usersRouter = require('./routes/users');
//...
app.use('/users', usersRouter);

4.4 ルーティングを追加してみる

./routes/user.jsを編集して、次のようなURLに対するルーティングを追加してみましょう。

http://localhost/users/123

Expressは、URLのパス部分のマッチング処理にPath-to-RegExpを使っており、ルーティングに正規表現を使うことができます。

Screen Shot 2019-06-25 at 12.22.26.png

https://www.npmjs.com/package/path-to-regexp

パターン マッチング例
'/ab+cd' abcd、abbcd、abbbcd など
'/ab*cd' abcd、abxcd、abRABDOMcd、ab123cd など
/a/ ルート名に「a」が含まれるすべてのもの
/.*fly$/ butterfly、 dragonflyなど

また、URL中の可変パラメータは、コロン記号を使って"/:userId"のように定義できます。

/:userId

捕捉された値はreq.paramsオブジェクトにセットされます。

req.params: { "userId": "123" }

それでは、./router/user.jsを開いて以下のようなハンドラを追加してみます。

./router/user.js
//
// ユーザーIDを指定できるルート
//
router.get('/:userId', function(req, res, next) {
  var userId = req.params.userId; // パラメータの値を取得
  console.log('ユーザーID '+userId+ ' が指定されました。'); // ログで確認
  res.send('ok'); // 必ず何らかのResponseを返す必要がある
});

このコードを、./router/user.jsに追加すると、user.js全体は以下のようになります。

./router/user.js
var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

//
// ユーザーIDを指定できるルート
//
router.get('/:userId', function(req, res, next) {
  var userId = req.params.userId; // パラメータの値を取得
  console.log('ユーザーID '+userId+ ' が指定されました。'); // ログで確認
  res.send('ok'); // 必ず何らかのResponseを返す必要がある
});

module.exports = router;

4.5 アプリを起動して確認する
$ npm start

プラウザで以下のURLにアクセスしてみましょう。

http://localhost:3000/users/123

okと表示されれば成功です。

Screen Shot 2019-06-21 at 15.21.52.png

また、アプリの起動コマンド$ npm startを実行したターミナルで、「ユーザーID123が指定されました」が表示されていれば、パラメータが正しく渡っています。

Screen Shot 2019-06-21 at 15.22.05.png

以上でチュートリアルの第1回は終わりです。

第1回のまとめ

インストールから起動までのコマンド

$ npm install express-generator -g
$ express --view=ejs myapp
$ cd myapp
$ npm install
$ npm start

確認URL

http://localhost:3000/

ルーティングを追加

router.get('/:userId', function(req, res, next) {
  var userId = req.params.userId; // パラメータの値を取得
  console.log('ユーザーID '+userId+ ' が指定されました。'); // ログで確認
  res.send('ok'); // 必ず何らかのResponseを返す必要がある
});

確認URL

http://localhost/users/123

第2回目はデータベース接続について学びます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Express.js の使い方【1】セットアップからルーティング

第1回

1 Expressとは
2 セットアップ
3 Expressの構造
4 ルーティング

第2回

5 データベース

第3回

6 MVCアーキテクチャー

--- 以降は準備中です ---
第4回以降

7 Request、Response オブジェクト
8 Vue.jsと連携
9 cookie
10 session
11 環境変数の利用
12 エラーハンドリング
13 セキュリティ
14 HTTPS
15 プロセスマネージャー (PM2)

1. Expressとは

ExpressはNode.js上で稼働するサーバーサイドのWEBアプリケーションフレームワークです。公式サイトの言葉を借りると、ExpressはFast(高速)で、Unopinionated(自説に固執しない)で、Minimalist(ミニマリスト)な、Node.js用Webフレームワークです。

Screen Shot 2019-06-20 at 22.09.17.png
https://expressjs.com/

この言葉にあるように、ExpressはNodeの特徴でもある高速性を重視しているため、Express本体は最小限で最軽量な構成になっています。ORM(DBのインターフェース)もなければ、テンプレートエンジンもない状態です。これらの機能に関しては必要に応じてパッケージを加えていくことになりますが、「どのような構成がよいか?」ということに関してExpressのスタンスはUnopinionatedなので、そこはプログラマの意思に委ねられているというわけです。このようなExpressの設計思想は、下図のようにRuby on RailsやLaravelと比較すると解りやすいかもしれません。

Screen Shot 2019-06-20 at 23.12.16.png

2018年にNode.js Foundationが行ったユーザー調査「2018 Node.js User Survey Report」では、Expressが人気フレームワークの1位になっています。

Screen Shot 2019-06-24 at 17.24.50.png

https://nodejs.org/en/user-survey-report#Tools-Technologies-Used

1.1 Express ジェネレータとは

express-generatorはアプリケーション・スケルトンを作成するためのツールです。スケルトンは、他のフレームワークではScaffold(足場)とよばれることもあります。
express-generatorは、npm パッケージとしてExpress本体とは別にインストールします。

1.2 今回作成するもの

第1回〜3回のレッスンでは、Expressジェネレータを使ったWEBアプリの実装方法をざっくり把握することを目的とし、「データベースに保存されたユーザーのリストを画面に表示する」という機能を作成します。この機能に特に実用性はありませんが、以下のようなポイントを把握できると思います。

  • express-generator (スケルトン生成)
  • ルーティング
  • MVC (Model View Controller)
  • ORM (Object-Rerational Mapping)
  • RDB (Rerational Database)
  • テンプレートエンジン

2 セットアップ

ExpressのHello Worldには2段階あります。

1つ目は、Express ジェネレータを使わないで素のExpressだけで表示するHello Worldです。この実装方法に関しては、公式ページに解りやすいマニュアルがありまし、スキップすることもできるので、ここでは特に触れないことにします。
https://expressjs.com/ja/starter/installing.html
https://expressjs.com/ja/starter/hello-world.html

2つ目は、Express ジェネレータでスケルトンを作成して表示するHello Worldです。
今回はここから進めていきます。

2.1 Express ジェネレータをインストールする

nodeはインストール済みという前提で、Expressジェネレータのインストールから始めます。以下のコマンドを実行してexpress-generatorをインストールします。

$ npm install express-generator -g

インストールが成功したことを確認するために、ヘルプ情報を表示してみます。

$ express -h

ヘルプ情報が表示されれば成功です。

2.2 スケルトンを生成

それではスケルトンを作成します。(スケルトンはScaffold(足場)と呼ばれることもあります。)スケルトンの作成にはexpressコマンドを使います。コマンドの引数に、テンプレートエンジンの種類と、アプリケーション名を指定します。

$ express --view=[テンプレートエンジンの種類] [アプリケーション名]

今回はテンプレートエンジンにEJSを使うことにし、アプリケーション名を「myapp」にします。

$ express --view=ejs myapp

コマンドを実行すると、下図のようなスケルトンが生成されます。

スクリーンショット 2019-06-11 19.40.57.png

モジュールの依存情報がpackage.jsonに定義されていますので、モジュールをインストールしましょう。

2.3 Nodeモジュールをインストールする

次のコマンドを実行してモジュールをインストールします。

$ cd myapp
$ npm install

コマンドを実行するとnode_modulesディレクトリにモジュールがインストールされ、以下のようなフォルダ構成になります。

スクリーンショット 2019-06-11 19.44.55.png

2.4 アプリを起動してみる

$ npm start

ブラウザで以下のURLを開いてみましょう。

http://localhost:3000/

ExpressのWelcome画面が表示されれば成功です。

Screen Shot 2019-06-21 at 15.13.23.png

スケルトンにはもうひとつ/users/というページが存在しています。この後のレッスンで使いますので、以下のURLも開いてみましょう。

http://localhost:3000/users/

respond with a resourceという文字が表示されれば成功です。

Screen Shot 2019-06-25 at 12.01.50.png

確認ができたらCtrl+cで終了しておきましょう。

3. Expressの構造

3.1 スケルトンの初期状態

Expressジェネレータが生成したスケルトンは、下図のような構造で動作しています。

Screen Shot 2019-06-25 at 10.41.37.png

  • HTTPリクエストを3000番ポートでListenします。
  • HTTPリクエストの情報は、reqという名前のオブジェクトにセットされます。
  • ルーティング機能が、URLのパスに応じて、処理のルートを振り分けます。
  • TOPページの表示には、Viewエンジン(今回はEJS)が使われています。
  • 静的ファイルへのリクエストは、/publicフォルダにルーティングされます。
  • HTTPレスポンスは、resという名前のオブジェクトを使って返します。

この先は、このスケルトンを出発点として、いろいろな機能を肉付けしていくことになります。

3.2 アプリ起動からルーティングまでの流れ

アプリの起動からルーティング処理までの流れを見てみます。ターミナルから起動コマンド$ npm startを実行すると、package.jsonのstartに登録されているnode ./bin/wwwが実行されます。

package.json
...
"scripts": {
    "start": "node ./bin/www"
  },
...

/bin/wwwはHTTPサーバーを実行し、メインスクリプトのapp.jsと結びつけます。その後は、HTTPリクエストが発生する度に、URLのパスに対応したルーティングのハンドラが実行されます。

Screen Shot 2019-06-24 at 13.49.03.png

Expressでページを追加するときは、そのページのルーティングを設定し、ページの機能やビューと結びつけるといううことを行っていきます。

4. ルーティング

4.1 ルーティングとは

Expressアプリは、HTTPリクエストを受けとってレスポンスを返します。ルーティングとは、受け取ったURLのパスに対して、アプリでどんな処理をするのかという処理の流れを実装することです。例えば、エンドユーザーがアプリケーションに対して、http://localhost/users/というURLでアクセスしたとします。そのとき、/users/というパスに対してどのようなレスポンスを返すのか、アプリケーションで実装します。

Screen Shot 2019-06-21 at 7.26.23.png

Node.jsでWebアプリを作るのが初めての方にとっては、ルーティングを実装するという感覚が新鮮かもしれません。Node.js以外の言語を使う場合、ルーティング処理はApacheなどのWebサーバーが担当します。

Screen Shot 2019-06-21 at 7.40.26.png

また、Apacheなどの場合は、URLのパスとドキュメントルート以下の物理ファイルのパスは密接に関係していますが、Node.jsの場合は物理ファイルのパスを対応させることも、対応させないこともどちらも可能です。

Screen Shot 2019-06-21 at 8.14.54.png

Expressジェネレータが生成するスケルトンでは、静的なファイルに関してはpublicフォルダ以下に対応付けされており、プログラマが意識しなくても自動的にルーティングされます。動的な処理をするパスに関しては、プログラマがコードでルーティング処理を実装します。動的なルーティングの実装は、主にroutesディレクトリ以下に配置していきます。

Screen Shot 2019-06-21 at 8.58.28.png

4.2 静的ページのルーティング

静的ファイルに関しては/public/フォルダに割り当てられていますので、ここに簡単なHTMLページを配置してみます。ファイル名をhello.htmlとします。

Screen Shot 2019-06-26 at 8.59.36.png

hello.html
<!DOCTYPE html>
<html>
    <head>
        <title>Hello</title>
    </head>
    <body>
        <h2>Hello!</h2>
    </body>
</html>

アプリを起動して表示してみます。

$ npm start

ブラウザで以下のURLを開きます。

http://localhost:3000/hello.html

Hello!が表示されれば成功です。

Ctrl+cでアプリを終了します。

Screen Shot 2019-06-26 at 9.10.17.png

4.2 ルーティングを実装する

それでは動的なページに関して、実際にどのようにルーティングを実装するのか見ていきましょう。ルーティングは、URLのパスに対するハンドラfunctionという形で実装します。例えば http://localhost/users/ というURLに対するルーティングは、/users/ というパスと、それに対応するハンドラ function を対応させるように書きます。

スクリーンショット 2019-06-16 12.50.08.png

4.3 ルーティングの実装方法

ルーティングの定義

app.METHOD(PATH, HANDLER)
  • app : express のインスタンス
  • METHOD : get/post など
  • PATH : URLのパス部分
  • HANDLER : パスが一致したときに実行されるfunction

ルーティングの実装方法には、app.jsに直接書く方法と、モジュール化する方法の2種類あります。

(1) app.jsに直接書く方法
app.js
var express = require('express');
var app = express();
....
app.get('/', function (req, res) {
  res.send('Hello World!');
});

このようにapp.jsに直接ルーティングを書くことができるのですが、ルーティングが増えるにしたがって、app.jsのコードが肥大化してしまうという問題が起こります。そこで、次のようにルーティング機能をモジュール化する方法がサポートされています。

(2) モジュール化する方法

Express Routerという機能を使ってハンドラの部分を別ファイルに切り出すことができます。

Screen Shot 2019-06-21 at 12.51.37.png

Expressジェネレータが生成したスケルトンには、./routes/user.jsというファイルがあり、このような内容になっています。

./router/user.js
var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

module.exports = router;

app.js側では、外出しにしたルータモジュール(users.js)をrequireしておき、リクエストURLの'/user'というパスに対応づけられています。

./app.js
var usersRouter = require('./routes/users');
//...
app.use('/users', usersRouter);

4.4 ルーティングを追加してみる

./routes/user.jsを編集して、次のようなURLに対するルーティングを追加してみましょう。

http://localhost/users/123

Expressは、URLのパス部分のマッチング処理にPath-to-RegExpを使っており、ルーティングに正規表現を使うことができます。

Screen Shot 2019-06-25 at 12.22.26.png

https://www.npmjs.com/package/path-to-regexp

パターン マッチング例
'/ab+cd' abcd、abbcd、abbbcd など
'/ab*cd' abcd、abxcd、abRABDOMcd、ab123cd など
/a/ ルート名に「a」が含まれるすべてのもの
/.*fly$/ butterfly、 dragonflyなど

また、URL中の可変パラメータは、コロン記号を使って"/:userId"のように定義できます。

/:userId

捕捉された値はreq.paramsオブジェクトにセットされます。

req.params: { "userId": "123" }

それでは、./router/user.jsを開いて以下のようなハンドラを追加してみます。

./router/user.js
//
// ユーザーIDを指定できるルート
//
router.get('/:userId', function(req, res, next) {
  var userId = req.params.userId; // パラメータの値を取得
  console.log('ユーザーID '+userId+ ' が指定されました。'); // ログで確認
  res.send('ok'); // 必ず何らかのResponseを返す必要がある
});

このコードを、./router/user.jsに追加すると、user.js全体は以下のようになります。

./router/user.js
var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

//
// ユーザーIDを指定できるルート
//
router.get('/:userId', function(req, res, next) {
  var userId = req.params.userId; // パラメータの値を取得
  console.log('ユーザーID '+userId+ ' が指定されました。'); // ログで確認
  res.send('ok'); // 必ず何らかのResponseを返す必要がある
});

module.exports = router;

4.5 アプリを起動して確認する
$ npm start

プラウザで以下のURLにアクセスしてみましょう。

http://localhost:3000/users/123

okと表示されれば成功です。

Screen Shot 2019-06-21 at 15.21.52.png

また、アプリの起動コマンド$ npm startを実行したターミナルで、「ユーザーID123が指定されました」が表示されていれば、パラメータが正しく渡っています。

Screen Shot 2019-06-21 at 15.22.05.png

以上でチュートリアルの第1回は終わりです。

第1回のまとめ

インストールから起動までのコマンド

$ npm install express-generator -g
$ express --view=ejs myapp
$ cd myapp
$ npm install
$ npm start

確認URL

http://localhost:3000/

ルーティングを追加

router.get('/:userId', function(req, res, next) {
  var userId = req.params.userId; // パラメータの値を取得
  console.log('ユーザーID '+userId+ ' が指定されました。'); // ログで確認
  res.send('ok'); // 必ず何らかのResponseを返す必要がある
});

確認URL

http://localhost/users/123

第2回目はデータベース接続について学びます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Express.jsを詳しく解説してみます 第1回

第1回

1 Expressとは
2 セットアップ
3 Expressの構造
4 ルーティング

第2回

5 データベース

第3回

6 MVCアーキテクチャー

--- 以降は準備中です ---
第4回以降

7 Request、Response オブジェクト
8 Vue.jsと連携
9 cookie
10 session
11 環境変数の利用
12 エラーハンドリング
13 セキュリティ
14 HTTPS
15 プロセスマネージャー (PM2)

1. Expressとは

ExpressはNode.js上で稼働するサーバーサイドのWEBアプリケーションフレームワークです。公式サイトの言葉を借りると、ExpressはFast(高速)で、Unopinionated(自説に固執しない)で、Minimalist(ミニマリスト)な、Node.js用Webフレームワークです。

Screen Shot 2019-06-20 at 22.09.17.png
https://expressjs.com/

この言葉にあるように、ExpressはNodeの特徴でもある高速性を重視しているため、Express本体は最小限で最軽量な構成になっています。ORM(DBのインターフェース)もなければ、テンプレートエンジンもない状態です。これらの機能に関しては必要に応じてパッケージを加えていくことになりますが、「どのような構成がよいか?」ということに関してExpressのスタンスはUnopinionatedなので、そこはプログラマの意思に委ねられているというわけです。このようなExpressの設計思想は、下図のようにRuby on RailsやLaravelと比較すると解りやすいかもしれません。

Screen Shot 2019-06-20 at 23.12.16.png

2018年にNode.js Foundationが行ったユーザー調査「2018 Node.js User Survey Report」では、Expressが人気フレームワークの1位になっています。

Screen Shot 2019-06-24 at 17.24.50.png

https://nodejs.org/en/user-survey-report#Tools-Technologies-Used

1.1 Express ジェネレータとは

express-generatorはアプリケーション・スケルトンを作成するためのツールです。スケルトンは、他のフレームワークではScaffold(足場)とよばれることもあります。
express-generatorは、npm パッケージとしてExpress本体とは別にインストールします。

1.2 今回作成するもの

第1回〜3回のレッスンでは、Expressジェネレータを使ったWEBアプリの実装方法をざっくり把握することを目的とし、「データベースに保存されたユーザーのリストを画面に表示する」という機能を作成します。この機能に特に実用性はありませんが、以下のようなポイントを把握できると思います。

  • express-generator (スケルトン生成)
  • ルーティング
  • MVC (Model View Controller)
  • ORM (Object-Rerational Mapping)
  • RDB (Rerational Database)
  • テンプレートエンジン

2 セットアップ

ExpressのHello Worldには2段階あります。

1つ目は、Express ジェネレータを使わないで素のExpressだけで表示するHello Worldです。この実装方法に関しては、公式ページに解りやすいマニュアルがありまし、スキップすることもできるので、ここでは特に触れないことにします。
https://expressjs.com/ja/starter/installing.html
https://expressjs.com/ja/starter/hello-world.html

2つ目は、Express ジェネレータでスケルトンを作成して表示するHello Worldです。
今回はここから進めていきます。

2.1 Express ジェネレータをインストールする

nodeはインストール済みという前提で、Expressジェネレータのインストールから始めます。以下のコマンドを実行してexpress-generatorをインストールします。

$ npm install express-generator -g

インストールが成功したことを確認するために、ヘルプ情報を表示してみます。

$ express -h

ヘルプ情報が表示されれば成功です。

2.2 スケルトンを生成

それではスケルトンを作成します。(スケルトンはScaffold(足場)と呼ばれることもあります。)スケルトンの作成にはexpressコマンドを使います。コマンドの引数に、テンプレートエンジンの種類と、アプリケーション名を指定します。

$ express --view=[テンプレートエンジンの種類] [アプリケーション名]

今回はテンプレートエンジンにEJSを使うことにし、アプリケーション名を「myapp」にします。

$ express --view=ejs myapp

コマンドを実行すると、下図のようなスケルトンが生成されます。

スクリーンショット 2019-06-11 19.40.57.png

モジュールの依存情報がpackage.jsonに定義されていますので、モジュールをインストールしましょう。

2.3 Nodeモジュールをインストールする

次のコマンドを実行してモジュールをインストールします。

$ cd myapp
$ npm install

コマンドを実行するとnode_modulesディレクトリにモジュールがインストールされ、以下のようなフォルダ構成になります。

スクリーンショット 2019-06-11 19.44.55.png

2.4 アプリを起動してみる

$ npm start

ブラウザで以下のURLを開いてみましょう。

http://localhost:3000/

ExpressのWelcome画面が表示されれば成功です。

Screen Shot 2019-06-21 at 15.13.23.png

スケルトンにはもうひとつ/users/というページが存在しています。この後のレッスンで使いますので、以下のURLも開いてみましょう。

http://localhost:3000/users/

respond with a resourceという文字が表示されれば成功です。

Screen Shot 2019-06-25 at 12.01.50.png

確認ができたらCtrl+cで終了しておきましょう。

3. Expressの構造

3.1 スケルトンの初期状態

Expressジェネレータが生成したスケルトンは、下図のような構造で動作しています。

Screen Shot 2019-06-25 at 10.41.37.png

  • HTTPリクエストを3000番ポートでListenします。
  • HTTPリクエストの情報は、reqという名前のオブジェクトにセットされます。
  • ルーティング機能が、URLのパスに応じて、処理のルートを振り分けます。
  • TOPページの表示には、Viewエンジン(今回はEJS)が使われています。
  • 静的ファイルへのリクエストは、/publicフォルダにルーティングされます。
  • HTTPレスポンスは、resという名前のオブジェクトを使って返します。

この先は、このスケルトンを出発点として、いろいろな機能を肉付けしていくことになります。

3.2 アプリ起動からルーティングまでの流れ

アプリの起動からルーティング処理までの流れを見てみます。ターミナルから起動コマンド$ npm startを実行すると、package.jsonのstartに登録されているnode ./bin/wwwが実行されます。

package.json
...
"scripts": {
    "start": "node ./bin/www"
  },
...

/bin/wwwはHTTPサーバーを実行し、メインスクリプトのapp.jsと結びつけます。その後は、HTTPリクエストが発生する度に、URLのパスに対応したルーティングのハンドラが実行されます。

Screen Shot 2019-06-24 at 13.49.03.png

Expressでページを追加するときは、そのページのルーティングを設定し、ページの機能やビューと結びつけるといううことを行っていきます。

4. ルーティング

4.1 ルーティングとは

Expressアプリは、HTTPリクエストを受けとってレスポンスを返します。ルーティングとは、受け取ったURLのパスに対して、アプリでどんな処理をするのかという処理の流れを実装することです。例えば、エンドユーザーがアプリケーションに対して、http://localhost/users/というURLでアクセスしたとします。そのとき、/users/というパスに対してどのようなレスポンスを返すのか、アプリケーションで実装します。

Screen Shot 2019-06-21 at 7.26.23.png

Node.jsでWebアプリを作るのが初めての方にとっては、ルーティングを実装するという感覚が新鮮かもしれません。Node.js以外の言語を使う場合、ルーティング処理はApacheなどのWebサーバーが担当します。

Screen Shot 2019-06-21 at 7.40.26.png

また、Apacheなどの場合は、URLのパスとドキュメントルート以下の物理ファイルのパスは密接に関係していますが、Node.jsの場合は物理ファイルのパスを対応させることも、対応させないこともどちらも可能です。

Screen Shot 2019-06-21 at 8.14.54.png

Expressジェネレータが生成するスケルトンでは、静的なファイルに関してはpublicフォルダ以下に対応付けされており、プログラマが意識しなくても自動的にルーティングされます。動的な処理をするパスに関しては、プログラマがコードでルーティング処理を実装します。動的なルーティングの実装は、主にroutesディレクトリ以下に配置していきます。

Screen Shot 2019-06-21 at 8.58.28.png

4.2 静的ページのルーティング

静的ファイルに関しては/public/フォルダに割り当てられていますので、ここに簡単なHTMLページを配置してみます。ファイル名をhello.htmlとします。

Screen Shot 2019-06-26 at 8.59.36.png

hello.html
<!DOCTYPE html>
<html>
    <head>
        <title>Hello</title>
    </head>
    <body>
        <h2>Hello!</h2>
    </body>
</html>

アプリを起動して表示してみます。

$ npm start

ブラウザで以下のURLを開きます。

http://localhost:3000/hello.html

Hello!が表示されれば成功です。

Ctrl+cでアプリを終了します。

Screen Shot 2019-06-26 at 9.10.17.png

4.2 ルーティングを実装する

それでは動的なページに関して、実際にどのようにルーティングを実装するのか見ていきましょう。ルーティングは、URLのパスに対するハンドラfunctionという形で実装します。例えば http://localhost/users/ というURLに対するルーティングは、/users/ というパスと、それに対応するハンドラ function を対応させるように書きます。

スクリーンショット 2019-06-16 12.50.08.png

4.3 ルーティングの実装方法

ルーティングの定義

app.METHOD(PATH, HANDLER)
  • app : express のインスタンス
  • METHOD : get/post など
  • PATH : URLのパス部分
  • HANDLER : パスが一致したときに実行されるfunction

ルーティングの実装方法には、app.jsに直接書く方法と、モジュール化する方法の2種類あります。

(1) app.jsに直接書く方法
app.js
var express = require('express');
var app = express();
....
app.get('/', function (req, res) {
  res.send('Hello World!');
});

このようにapp.jsに直接ルーティングを書くことができるのですが、ルーティングが増えるにしたがって、app.jsのコードが肥大化してしまうという問題が起こります。そこで、次のようにルーティング機能をモジュール化する方法がサポートされています。

(2) モジュール化する方法

Express Routerという機能を使ってハンドラの部分を別ファイルに切り出すことができます。

Screen Shot 2019-06-21 at 12.51.37.png

Expressジェネレータが生成したスケルトンには、./routes/user.jsというファイルがあり、このような内容になっています。

./router/user.js
var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

module.exports = router;

app.js側では、外出しにしたルータモジュール(users.js)をrequireしておき、リクエストURLの'/user'というパスに対応づけられています。

./app.js
var usersRouter = require('./routes/users');
//...
app.use('/users', usersRouter);

4.4 ルーティングを追加してみる

./routes/user.jsを編集して、次のようなURLに対するルーティングを追加してみましょう。

http://localhost/users/123

Expressは、URLのパス部分のマッチング処理にPath-to-RegExpを使っており、ルーティングに正規表現を使うことができます。

Screen Shot 2019-06-25 at 12.22.26.png

https://www.npmjs.com/package/path-to-regexp

パターン マッチング例
'/ab+cd' abcd、abbcd、abbbcd など
'/ab*cd' abcd、abxcd、abRABDOMcd、ab123cd など
/a/ ルート名に「a」が含まれるすべてのもの
/.*fly$/ butterfly、 dragonflyなど

また、URL中の可変パラメータは、コロン記号を使って"/:userId"のように定義できます。

/:userId

捕捉された値はreq.paramsオブジェクトにセットされます。

req.params: { "userId": "123" }

それでは、./router/user.jsを開いて以下のようなハンドラを追加してみます。

./router/user.js
//
// ユーザーIDを指定できるルート
//
router.get('/:userId', function(req, res, next) {
  var userId = req.params.userId; // パラメータの値を取得
  console.log('ユーザーID '+userId+ ' が指定されました。'); // ログで確認
  res.send('ok'); // 必ず何らかのResponseを返す必要がある
});

このコードを、./router/user.jsに追加すると、user.js全体は以下のようになります。

./router/user.js
var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

//
// ユーザーIDを指定できるルート
//
router.get('/:userId', function(req, res, next) {
  var userId = req.params.userId; // パラメータの値を取得
  console.log('ユーザーID '+userId+ ' が指定されました。'); // ログで確認
  res.send('ok'); // 必ず何らかのResponseを返す必要がある
});

module.exports = router;

4.5 アプリを起動して確認する
$ npm start

プラウザで以下のURLにアクセスしてみましょう。

http://localhost:3000/users/123

okと表示されれば成功です。

Screen Shot 2019-06-21 at 15.21.52.png

また、アプリの起動コマンド$ npm startを実行したターミナルで、「ユーザーID123が指定されました」が表示されていれば、パラメータが正しく渡っています。

Screen Shot 2019-06-21 at 15.22.05.png

以上でチュートリアルの第1回は終わりです。

第1回のまとめ

インストールから起動までのコマンド

$ npm install express-generator -g
$ express --view=ejs myapp
$ cd myapp
$ npm install
$ npm start

確認URL

http://localhost:3000/

ルーティングを追加

router.get('/:userId', function(req, res, next) {
  var userId = req.params.userId; // パラメータの値を取得
  console.log('ユーザーID '+userId+ ' が指定されました。'); // ログで確認
  res.send('ok'); // 必ず何らかのResponseを返す必要がある
});

確認URL

http://localhost/users/123

第2回目はデータベース接続について学びます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Express.jsをわかりやすく解説してみます 第1回

第1回

1 Expressとは
2 セットアップ
3 Expressの構造
4 ルーティング

第2回

5 データベース

第3回

6 MVCアーキテクチャー

--- 以降は準備中です ---
第4回以降

7 Request、Response オブジェクト
8 Vue.jsと連携
9 cookie
10 session
11 環境変数の利用
12 エラーハンドリング
13 セキュリティ
14 HTTPS
15 プロセスマネージャー (PM2)

1. Expressとは

ExpressはNode.js上で稼働するサーバーサイドのWEBアプリケーションフレームワークです。公式サイトの言葉を借りると、ExpressはFast(高速)で、Unopinionated(自説に固執しない)で、Minimalist(ミニマリスト)な、Node.js用Webフレームワークです。

Screen Shot 2019-06-20 at 22.09.17.png
https://expressjs.com/

この言葉にあるように、ExpressはNodeの特徴でもある高速性を重視しているため、Express本体は最小限で最軽量な構成になっています。ORM(DBのインターフェース)もなければ、テンプレートエンジンもない状態です。これらの機能に関しては必要に応じてパッケージを加えていくことになりますが、「どのような構成がよいか?」ということに関してExpressのスタンスはUnopinionatedなので、そこはプログラマの意思に委ねられているというわけです。このようなExpressの設計思想は、下図のようにRuby on RailsやLaravelと比較すると解りやすいかもしれません。

Screen Shot 2019-06-20 at 23.12.16.png

2018年にNode.js Foundationが行ったユーザー調査「2018 Node.js User Survey Report」では、Expressが人気フレームワークの1位になっています。

Screen Shot 2019-06-24 at 17.24.50.png

https://nodejs.org/en/user-survey-report#Tools-Technologies-Used

1.1 Express ジェネレータとは

express-generatorはアプリケーション・スケルトンを作成するためのツールです。スケルトンは、他のフレームワークではScaffold(足場)とよばれることもあります。
express-generatorは、npm パッケージとしてExpress本体とは別にインストールします。

1.2 今回作成するもの

第1回〜3回のレッスンでは、Expressジェネレータを使ったWEBアプリの実装方法をざっくり把握することを目的とし、「データベースに保存されたユーザーのリストを画面に表示する」という機能を作成します。この機能に特に実用性はありませんが、以下のようなポイントを把握できると思います。

  • express-generator (スケルトン生成)
  • ルーティング
  • MVC (Model View Controller)
  • ORM (Object-Rerational Mapping)
  • RDB (Rerational Database)
  • テンプレートエンジン

2 セットアップ

ExpressのHello Worldには2段階あります。

1つ目は、Express ジェネレータを使わないで素のExpressだけで表示するHello Worldです。この実装方法に関しては、公式ページに解りやすいマニュアルがありまし、スキップすることもできるので、ここでは特に触れないことにします。
https://expressjs.com/ja/starter/installing.html
https://expressjs.com/ja/starter/hello-world.html

2つ目は、Express ジェネレータでスケルトンを作成して表示するHello Worldです。
今回はここから進めていきます。

2.1 Express ジェネレータをインストールする

nodeはインストール済みという前提で、Expressジェネレータのインストールから始めます。以下のコマンドを実行してexpress-generatorをインストールします。

$ npm install express-generator -g

インストールが成功したことを確認するために、ヘルプ情報を表示してみます。

$ express -h

ヘルプ情報が表示されれば成功です。

2.2 スケルトンを生成

それではスケルトンを作成します。(スケルトンはScaffold(足場)と呼ばれることもあります。)スケルトンの作成にはexpressコマンドを使います。コマンドの引数に、テンプレートエンジンの種類と、アプリケーション名を指定します。

$ express --view=[テンプレートエンジンの種類] [アプリケーション名]

今回はテンプレートエンジンにEJSを使うことにし、アプリケーション名を「myapp」にします。

$ express --view=ejs myapp

コマンドを実行すると、下図のようなスケルトンが生成されます。

スクリーンショット 2019-06-11 19.40.57.png

モジュールの依存情報がpackage.jsonに定義されていますので、モジュールをインストールしましょう。

2.3 Nodeモジュールをインストールする

次のコマンドを実行してモジュールをインストールします。

$ cd myapp
$ npm install

コマンドを実行するとnode_modulesディレクトリにモジュールがインストールされ、以下のようなフォルダ構成になります。

スクリーンショット 2019-06-11 19.44.55.png

2.4 アプリを起動してみる

$ npm start

ブラウザで以下のURLを開いてみましょう。

http://localhost:3000/

ExpressのWelcome画面が表示されれば成功です。

Screen Shot 2019-06-21 at 15.13.23.png

スケルトンにはもうひとつ/users/というページが存在しています。この後のレッスンで使いますので、以下のURLも開いてみましょう。

http://localhost:3000/users/

respond with a resourceという文字が表示されれば成功です。

Screen Shot 2019-06-25 at 12.01.50.png

確認ができたらCtrl+cで終了しておきましょう。

3. Expressの構造

3.1 スケルトンの初期状態

Expressジェネレータが生成したスケルトンは、下図のような構造で動作しています。

Screen Shot 2019-06-25 at 10.41.37.png

  • HTTPリクエストを3000番ポートでListenします。
  • HTTPリクエストの情報は、reqという名前のオブジェクトにセットされます。
  • ルーティング機能が、URLのパスに応じて、処理のルートを振り分けます。
  • TOPページの表示には、Viewエンジン(今回はEJS)が使われています。
  • 静的ファイルへのリクエストは、/publicフォルダにルーティングされます。
  • HTTPレスポンスは、resという名前のオブジェクトを使って返します。

この先は、このスケルトンを出発点として、いろいろな機能を肉付けしていくことになります。

3.2 アプリ起動からルーティングまでの流れ

アプリの起動からルーティング処理までの流れを見てみます。ターミナルから起動コマンド$ npm startを実行すると、package.jsonのstartに登録されているnode ./bin/wwwが実行されます。

package.json
...
"scripts": {
    "start": "node ./bin/www"
  },
...

/bin/wwwはHTTPサーバーを実行し、メインスクリプトのapp.jsと結びつけます。その後は、HTTPリクエストが発生する度に、URLのパスに対応したルーティングのハンドラが実行されます。

Screen Shot 2019-06-24 at 13.49.03.png

Expressでページを追加するときは、そのページのルーティングを設定し、ページの機能やビューと結びつけるといううことを行っていきます。

4. ルーティング

4.1 ルーティングとは

Expressアプリは、HTTPリクエストを受けとってレスポンスを返します。ルーティングとは、受け取ったURLのパスに対して、アプリでどんな処理をするのかという処理の流れを実装することです。例えば、エンドユーザーがアプリケーションに対して、http://localhost/users/というURLでアクセスしたとします。そのとき、/users/というパスに対してどのようなレスポンスを返すのか、アプリケーションで実装します。

Screen Shot 2019-06-21 at 7.26.23.png

Node.jsでWebアプリを作るのが初めての方にとっては、ルーティングを実装するという感覚が新鮮かもしれません。Node.js以外の言語を使う場合、ルーティング処理はApacheなどのWebサーバーが担当します。

Screen Shot 2019-06-21 at 7.40.26.png

また、Apacheなどの場合は、URLのパスとドキュメントルート以下の物理ファイルのパスは密接に関係していますが、Node.jsの場合は物理ファイルのパスを対応させることも、対応させないこともどちらも可能です。

Screen Shot 2019-06-21 at 8.14.54.png

Expressジェネレータが生成するスケルトンでは、静的なファイルに関してはpublicフォルダ以下に対応付けされており、プログラマが意識しなくても自動的にルーティングされます。動的な処理をするパスに関しては、プログラマがコードでルーティング処理を実装します。動的なルーティングの実装は、主にroutesディレクトリ以下に配置していきます。

Screen Shot 2019-06-21 at 8.58.28.png

4.2 静的ページのルーティング

静的ファイルに関しては/public/フォルダに割り当てられていますので、ここに簡単なHTMLページを配置してみます。ファイル名をhello.htmlとします。

Screen Shot 2019-06-26 at 8.59.36.png

hello.html
<!DOCTYPE html>
<html>
    <head>
        <title>Hello</title>
    </head>
    <body>
        <h2>Hello!</h2>
    </body>
</html>

アプリを起動して表示してみます。

$ npm start

ブラウザで以下のURLを開きます。

http://localhost:3000/hello.html

Hello!が表示されれば成功です。

Ctrl+cでアプリを終了します。

Screen Shot 2019-06-26 at 9.10.17.png

4.2 ルーティングを実装する

それでは動的なページに関して、実際にどのようにルーティングを実装するのか見ていきましょう。ルーティングは、URLのパスに対するハンドラfunctionという形で実装します。例えば http://localhost/users/ というURLに対するルーティングは、/users/ というパスと、それに対応するハンドラ function を対応させるように書きます。

スクリーンショット 2019-06-16 12.50.08.png

4.3 ルーティングの実装方法

ルーティングの定義

app.METHOD(PATH, HANDLER)
  • app : express のインスタンス
  • METHOD : get/post など
  • PATH : URLのパス部分
  • HANDLER : パスが一致したときに実行されるfunction

ルーティングの実装方法には、app.jsに直接書く方法と、モジュール化する方法の2種類あります。

(1) app.jsに直接書く方法
app.js
var express = require('express');
var app = express();
....
app.get('/', function (req, res) {
  res.send('Hello World!');
});

このようにapp.jsに直接ルーティングを書くことができるのですが、ルーティングが増えるにしたがって、app.jsのコードが肥大化してしまうという問題が起こります。そこで、次のようにルーティング機能をモジュール化する方法がサポートされています。

(2) モジュール化する方法

Express Routerという機能を使ってハンドラの部分を別ファイルに切り出すことができます。

Screen Shot 2019-06-21 at 12.51.37.png

Expressジェネレータが生成したスケルトンには、./routes/user.jsというファイルがあり、このような内容になっています。

./router/user.js
var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

module.exports = router;

app.js側では、外出しにしたルータモジュール(users.js)をrequireしておき、リクエストURLの'/user'というパスに対応づけられています。

./app.js
var usersRouter = require('./routes/users');
//...
app.use('/users', usersRouter);

4.4 ルーティングを追加してみる

./routes/user.jsを編集して、次のようなURLに対するルーティングを追加してみましょう。

http://localhost/users/123

Expressは、URLのパス部分のマッチング処理にPath-to-RegExpを使っており、ルーティングに正規表現を使うことができます。

Screen Shot 2019-06-25 at 12.22.26.png

https://www.npmjs.com/package/path-to-regexp

パターン マッチング例
'/ab+cd' abcd、abbcd、abbbcd など
'/ab*cd' abcd、abxcd、abRABDOMcd、ab123cd など
/a/ ルート名に「a」が含まれるすべてのもの
/.*fly$/ butterfly、 dragonflyなど

また、URL中の可変パラメータは、コロン記号を使って"/:userId"のように定義できます。

/:userId

捕捉された値はreq.paramsオブジェクトにセットされます。

req.params: { "userId": "123" }

それでは、./router/user.jsを開いて以下のようなハンドラを追加してみます。

./router/user.js
//
// ユーザーIDを指定できるルート
//
router.get('/:userId', function(req, res, next) {
  var userId = req.params.userId; // パラメータの値を取得
  console.log('ユーザーID '+userId+ ' が指定されました。'); // ログで確認
  res.send('ok'); // 必ず何らかのResponseを返す必要がある
});

このコードを、./router/user.jsに追加すると、user.js全体は以下のようになります。

./router/user.js
var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

//
// ユーザーIDを指定できるルート
//
router.get('/:userId', function(req, res, next) {
  var userId = req.params.userId; // パラメータの値を取得
  console.log('ユーザーID '+userId+ ' が指定されました。'); // ログで確認
  res.send('ok'); // 必ず何らかのResponseを返す必要がある
});

module.exports = router;

4.5 アプリを起動して確認する
$ npm start

プラウザで以下のURLにアクセスしてみましょう。

http://localhost:3000/users/123

okと表示されれば成功です。

Screen Shot 2019-06-21 at 15.21.52.png

また、アプリの起動コマンド$ npm startを実行したターミナルで、「ユーザーID123が指定されました」が表示されていれば、パラメータが正しく渡っています。

Screen Shot 2019-06-21 at 15.22.05.png

以上でチュートリアルの第1回は終わりです。

第1回のまとめ

インストールから起動までのコマンド

$ npm install express-generator -g
$ express --view=ejs myapp
$ cd myapp
$ npm install
$ npm start

確認URL

http://localhost:3000/

ルーティングを追加

router.get('/:userId', function(req, res, next) {
  var userId = req.params.userId; // パラメータの値を取得
  console.log('ユーザーID '+userId+ ' が指定されました。'); // ログで確認
  res.send('ok'); // 必ず何らかのResponseを返す必要がある
});

確認URL

http://localhost/users/123

第2回目はデータベース接続について学びます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

国連ベクトルタイル関連活動の現在時点の全体像

私の関わっている国連ベクトルタイル関連活動の現在時点の全体像は、次の通りだと思っています。

  1. 国連ベクトルタイルツールキット本体
  2. 国連事務局への個別支援
  3. Docker 実装(RPi 上の実装を含む)
  4. Adopt Geodata
  5. 新ハンズオン資料 ango
  6. その他の新展開
    1. HOCON で Mapbox Style を合理的に記述する
    2. 屋内地図への展開
    3. 生産フェーズでの mokuroku との接続
  7. FOSS4G 2019 Bucharest でのプレゼンテーション準備

それぞれについて、あとで書きます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Node.JSのSequelize ORM入門

開発者はもう観察しているように、バックエンドウェブ開発のためのExpress.JSというフレームワークが少しずつ人気になっています。それに加えて、Express.JSはMongoose ORMと共に、一般的にREST APIの作成に使います。しかし、MySQL、PostgreSQL、SQLiteなどのような他のDatabase Schemaを使いたい開発者の場合に、どうするのか?SQLに関するデータベース言語のための探せるORMがどこかにありますか?ありがたいことに、そんなことがあります。こういうことはSequelizeというORMです。前の書いた記事とは違って、この記事にExpress.JSにデータベースを統合するという話が書いてあります。これから、Express.JSをSequelizeで使用して開始する方法を紹介します。

こんにちは!マルクス(Twitter Account: @markusveeyola)と申します。現在、奥多摩日本語学校の学生で、同時に、IT開発者としてアルバイトをしています。宜しくお願い致します!

それでは、始めましょうか。

1__SmZzhgGpZ5tHeUM8toUWQ.jpeg

ORMとは

Object Relation Mappingというモデルはオブジェクトとリレーショナルデータベースの接続を手順としています。手動でSQLステートメントを書く必要性を排除するために使用されますが、むしろ、オブジェクトを通して、はるかに速くそしてより読みやすいQuery操作をすることができます。

Sequelizeとは

Sequelizeは、Node.js用のpromised-basedのORMです。それは習得が容易で、SynchronizationAssociationのような機能を持っています。Sequelizeで PostgreSQL、MySQL、MariaDB、SQLite、MSSQLはサポートされています。

前提条件

後は、申請をするとき、我々の手順が正しく機能するようにするために、これらは必要な条件です。

  • Node.jsとNPMはインストールした必要があります。
  • Node Package Manager「NPM」の基本的な知識
  • Node.jsの基本的な知識
  • Postman: HTTP Requestをテストするものを責任としています。
  • 設定したSQLデータベース

開発時間

プロジェクトを初期化するために、先ずはアプリを作りたい場所のフォルダに行ってください。そのフォルダーから、ターミナルに行って、「mkdir」コマンドラインを使って、プロジェクトの名前として「SequelizeCRUD」に付けて、入力してください。新しいフォルダーは作られるはずです。その後はそのフォルダーに行くため、「cd」コマンドラインと「SequelizeCRUD」を付けて、入力してください。

例: 
D:\Programming\Testing\> mkdir SequelizeCRUD
D:\Programming\Testing\> cd SequelizeCRUD
D:\Programming\Testing\SequelizeCRUD\>

SequelizeCRUD」フォルダーはもう作られたら、とうとうプロジェクトを始めるために、ターミナルからこのNPMのコードを入力してください。普通に、各々のコマンドライン実行の中には時間がかかるかもしれないので、しばらくお待ちください。

(ターミナルから作ったフォルダに行く必要です。)
npm init -y
npm install -g nodemon sequelize-cli
npm install -s express mysql2 sequelize body-parser

それでは、何が起こったんでしょうか。上のコードを見られるように、NPMの「init」を使って、プロジェクトを初期化するようになりました。初期化できた後、NPMの「install」でグローバルライブラリパッケージとしてsequelize-clinodemonをインストールするようになりました。sequelize-cliの目的は、アプリにORMコマンドを使用させるためです。次のインストールしたライブラリはREST APIアプリにデータベースを統合するものを目的としています。

必要なNPMパッケージはもうインストールされたので、今回は操作のコードを書き始めます!

最初は好んだコードエディタを開けてください。私にはVisual Studio Codeを使っています。エディタからSequelizeCRUDのフォルダーを開けてください。生成した「node_modules、package.json、package-lock.json」ファイル以外に、下のストラクチャーを基に他のフォルダapp.jsを作ってください。

SequelizeCRUD
    > config/ 
    > controllers/ 
    > migrations/ 
    > models/ 
    > routes/ 
    > app.js 
    > node_modules/
    > package.json
    > package-lock.json

今回は、コードを書く時間です!「app.js」ファイルに行ってください。後で、下のコードを全て入れてください。

const express = require('express');
const bodyParser = require('body-parser');
const http = require('http');
const app = express();
const port = 8000;

app.set('port', port);
app.use(bodyParser.json());

const server = http.createServer(app);
server.listen(port);
module.exports = app;

このファイルはウェブサービスを作るために、全てを縛るメインファイルです。だから、折々このファイルに戻ります。コードに見られたように、サーバーを設定するためのブラリとして、expressbody-parserhttpがインポートされました。そして、PORTとしては8000を使って、サーバーが確立されます。

次に、configというフォルダに行って、config.jsonを名前としてファイルを作ってください。また、提供したコードを入ってください。

{
  "development": {
    "username": "root",
    "password": "mysql",
    "database": "sequelize", 
    "host": "192.168.0.112",
    "dialect": "mysql"
  }
}

このファイルはデータベースの接続を設定するものを目的としています。あなたの好んだSQLに応じて、dialectというプロパティの価値になります。SQLデータベースに対応する必要なプロパティを変更してください。

さて、データベースのモデルを作り始める前に、モデルのフォルダにindex.jsを作るべきです。次の見せるコードをいれてください。

'use strict';

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const db = {};

let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config);
}

fs
  .readdirSync(__dirname)
  .filter(file => {
    return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
  })
  .forEach(file => {
    const model = sequelize['import'](path.join(__dirname, file));
    db[model.name] = model;
  });

Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

なぜ、こういうコードが必要なのか?理由は全てのモデルファイルを一つずつインポートするというより、むしろこのファイルがインポートの手順を自動化します。それに加えて、Sequelize ORMの接続をインスタンスするために、このところにconfig.jsonファイルから、先の設定した環境を使います。このため、SequelizeでデータベースのQueryを簡単に使えるようになります。

後は、これからモデルの作成に進めます。EmployeeCompanyのモデルを作ります。この2つの間にそれぞれのEmployeeが1つのCompanyで働いてて、逆でそれぞれのCompanyがたくさんEmployeeを持てるという関係になります。だから、後に、SequelizeでbelongsToOne-is-to-Oneを表し、hasManyOne-is-to-Manyを表すというassocationを使うと、テーブル関係を確立できるようになります。

ターミナルから、モデルを作るために、下の部分に書いてあるように、こうやって入力する:

// Employee
sequelize model:generate --name Employee --attributes name:string,salary:integer
// Company
sequelize model:generate --name Company --attributes name:string

「 sequelize-cliというライブラリはもうインストールされたから、こういうことができます。」

上のコマンドを正しく入力すれば、4つのファイルが生成されるはずです。このファイルは2つに分けられて、MigrationsModelsを一部としています。

Migrations: Company & Employee

'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Companies', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      name: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Companies');
  }
};

CompanyMigrationファイルが見られるように、idcreatedAtupdatedAtと共に、nameフィールドがすでに設定されています。

一方でEmployeeというMigrationにはnamesalaryの両方フィールドがあります。しかし、EmployeeCompany次第なので、手動で、FKフィールドはcompanyIdを名前として、追加するべきです。参照として、すでに下のコードでどのように書かれているかを見るはずです。

'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Employees', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      name: {
        type: Sequelize.STRING
      },
      salary: {
        type: Sequelize.INTEGER
      },
      companyId: {
        type: Sequelize.INTEGER,
        onDelete: 'CASCADE',
        references: {
          model: 'Companies',
          key: 'id',
        }
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Employees');
  }
};

今回は、データーベースのAssocationを設定するために、モデルに行きましょう。AssociationというSequelize特徴はQueryを簡単に作る上で、使う必要なのです。なぜなら、こういう特徴を使って、FKでお互いに接続されているテーブルにQueryを直接に作れます。

Models: Company & Employee

CompanyというモデルはOne-is-to-ManyCardinalityを持っているので、次に示すコードのようにHasManyというAssociationが使用されます。

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Company = sequelize.define('Company', {
    name: DataTypes.STRING
  }, {});
  Company.associate = function(models) {
    // associations can be defined here
    Company.hasMany(models.Employee, {
      foreignKey: 'companyId',
      as: 'employees',
    })
  };
  return Company;
};

次に、Employeeの場合に、One-is-to-ManyのCardinalityを持ってて、Company次第なので、BelongsToというAssocationを使います。

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Employee = sequelize.define('Employee', {
    name: DataTypes.STRING,
    salary: DataTypes.INTEGER
  }, {});
  Employee.associate = function(models) {
    // associations can be defined here
    Employee.belongsTo(models.Company, {
      foreignKey: 'companyId',
      onDelete: 'CASCADE',
    })
  };
  return Employee;
};

Model Synchronization

今、Associationをちゃんと作動してもらうものを目的として、モデルのメインファイルにシンクロナイズします。そうするために、app.jsに戻って、下の書いてあるコードと同じように、そういうコードをいれてください。Employeeモデルのウェブメソッドだけを作るので、Companyのデーターを直接にイニシャライズします。

このコードに表示しているように、モデル変数としてindex.jsをインポートしました。そういう変数を使ってCompanyのモデルを使えます。

const express = require('express');
const bodyParser = require('body-parser');
const http = require('http');
const models = require('./models/index.js');
const Company = models.Company;
const app = express();
const port = 8000;

app.set('port', port);
app.use(bodyParser.json());

models.sequelize.sync().then(() => {
    initial();
    console.log('Seems like the backend is running fine...');
}).catch((err) => {
    console.log(err, 'Something went wrong with the operation');
});

require('./routes/employee.route')(app);

function initial(){
    Company.create({
        name: "ABC Company"
    });
    Company.create({
        name: "DEF Company"
    });
    Company.create({
        name: "GHI Company"
    });
}

const server = http.createServer(app);
server.listen(port);
module.exports = app;

この後は、ターミナルに、設定したモデルをテーブルにするために、このようなコードを入力してください。

sequelize db:migrate

Controller: Employee

const db = require('../models/index.js');
const Employee = db.Employee;
const Company = db.Company;

module.exports = {
  create(req, res) {  
    Employee.create({  
      name: req.body.name,
      salary: req.body.salary,
      companyId: req.body.companyId, 
    }).then(employee => {    
      res.send(employee);
    });
  },
  findAll(req, res) {
    Employee.findAll({
      include: [{ model: Company }]
    }).then(companies => {
      res.send(companies);
    });
  },
  findOne(req, res) {  
    Employee.findOne({
      where: {
        id: req.params.id
      },
      include: [{ model: Company }]
    })
    .then(company => {
      res.send(company);
    })
  },
  update(req, res) {
    Employee.update(
      { 
        name: req.body.name,
        salary: req.body.salary
      }, {
        where: { id: req.params.id } 
      }
    ).then(() => {
        res.status(200).send("Successfully updated a Employee ID: " + req.params.id);
    });
  },
  delete(req, res) {
    Employee.destroy({
      where: { id: req.params.id }
    }).then(() => {
      res.status(200).send("Successfully deleted a Employee ID: " + req.params.id);
    });
  }
}

上に見せられるように、データベースにEmployeeCompanyのテーブルが生成されたので、Controllerを作る時間になりました。Controllerフォルダに行って、employee.controller.jsを名前として、新しいファイルを作ります。このところにウェブメソッドを作っていきます。Sequelize接続をアクセスするために、モデルフォルダのindex.jsファイルをインポートして、EmployeeCompanyのモデルを変数に入ります。

SequelizeはORMなので、手動でQueryを作らなくていいです。createfindAllfindOneupdatedestroyのような定義済み関数を使うだけです。また、一目瞭然の関数名前なので、使い方はすぐ分かります。SequelizeのQuerypromise-basedの関数だから、callbackerrorは管理しやすいです。

このコードのハイライトはそのfindOnefindAllというメソッドです。なぜなら、SequelizeのAssociationで、EmployeeのデーターをQueryでもらうと、includeのタッグを使ってCompanyのデーターも直接にもらえます。とても便利ですよね!

Route: Employee

自分でこのアプリをテストする前に、Routeフォルダに行って、最後の新しいファイルを作って、employee.route.jsを名前としていくべきです。

module.exports = function(app) {

    const employeesController = require('../controllers/employee.controller');
    const employeesAPI = '/api/employees'

    // Create a new Employee
    app.post(employeesAPI, employeesController.create);

    // Retrieve all Employees
    app.get(employeesAPI, employeesController.findAll);

    // Retrieve a Employee by ID
    app.get(employeesAPI + '/:id', employeesController.findOne);

    // Update a Employee by ID
    app.patch(employeesAPI + '/:id', employeesController.update);

    // Delete a Employee by ID
    app.delete(employeesAPI + '/:id', employeesController.delete);
};

コードに見られるように、先の作ったcontrollerをインポートして、controllerのエンドポイントを変数に保存しました。そして、それぞれの作ったメソッドにrouteがセットされました。

最終的に、app.jsファイルに戻って、その作ったrouteをインポートして、とうとうテストがもうできます。そうするために、ターミナルに行って、次に見せられるように、このコマンドように書きます:

nodemon app.js

もう今、PostmanHTTP Clientで、テストできますよ!

終わり

全部の手順を正確にすれば、作動しているExpressSequelizeを統合されたNode.js REST APIのアプリをもう書くようにできました!やったね!日本語勉強中なので、この記事は内容が分かりにくいかもしれなくても、読んで頑張ってありがとうございました! 

じゃあまたね!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む