【Node.js 超入門】Node.jsとExpessを使ってCRUD処理できるサーバサイドの実装をする!

JavaScript
スポンサーリンク

前書き

今回は【Node.js 超入門】という参考書を読んで、Node.jsでプログラミングを書いていきます。

目的

今回はデータベースを使って画面からユーザ情報を登録、更新などCRUD処理できるアプリケーションを作成します。

メインとしてNode.jsとExpressを使い、サーバサイドの処理を作ります。

データベースはMySQLを使います。

CRUD処理とは、以下の処理の頭文字をとったものでデータベースを使ったWebアプリケーションではたびたび使われます。

処理内容
Create(登録)新しいデータを登録する。
Read(参照)レコードをテーブルから取り出す。
Update(更新)レコードの内容を更新する。
Delete(削除)レコードを削除する。

前提条件

今回プログラミングを書くにあたって以下の知識があると理解しやすくなっています。

  • HTML(EJS)の書き方
  • JavaScriptの書き方
  • HTTP通信におけるリクエスト/レスポンスとは
  • HTTPメソッドのPOSTとGETの違い
  • npmとは、コマンドプロンプトの使い方
  • SQL文

Node.jsではサーバサイドをメインで実装しますが、クライアントサイドも実装する必要があります。HTML/やJavaScriptの知識だけでなく、HTTP通信といった通信の部分や、コマンドプロンプトの使い方といったコマンドについての知識も使うので幅広い知識が求められます。

【Node.js 超入門】はどんな本?

内容

こちらの参考書は大きくこちらの流れで書かれています。

  1. Node.jsとは/環境構築の方法
  2. Node.jsを使ったWebサーバーの開発
  3. Expressフレームワークを使用したWebサーバの開発
  4. データベースやその他モジュールを使って簡易掲示板の作成

この中で今回はExpressフレームワークも使用したWebサーバの開発をご説明します。

使用モジュール一覧

今回参考書で使用したモジュールの一覧とその説明はこちらです。

沢山ありますが全部覚える必要はないので、「こんなものがあるんだ」ぐらいの気持ちで見てください。気になったモジュールがあったらググってみてください。

なお使用するときは基本的にrequire()を使います。

//例
var http = require('http');
モジュール名説明
httphttpアクセスの機能を提供する。
fsファイルをを扱う。HTMLが使えるようになる。
ejsJavaScriptで利用するテンプレートエンジン。HTMLの上位互換。
urlURLを扱うための機能がまとめられている。
querystringクエリパラメータを処理するための機能。
expressNode.jsのフレームワーク。すごい便利。
body-parserexpressでフォームの利用に使う。
http-errorsExpressのエラーに関するもの。
pathファイルパスを扱うもの。
morganHTTPリクエストのログ出力に関するもの。
cookie-parsercookieの値の変換に関するもの。
express-sessionセッション機能に関するもの。
mysqlMySQLを扱うもの。
express-validatorバリデーションに関するもの。
knexSQLのクエリーを生成するためのもの。
bookshelfデータベースアクセスを行うもの。

環境構築

フォルダの作成

作業フォルダを作ります。

今回はnodeという名前で作成します。ここのパスはコマンドプロンプトでnpmをインストールするので、覚えていてください。

npmのインストール

npmをインストールして、node.jsを実行するために必要な環境を作ります。

まずは以下のNode.jsのサイトからNode.jsをインストールしてください。Node.jsには2種類ありますが、LTS(推奨版)をインストールしてください。

https://nodejs.org/ja/

インストールが終わったらコマンドプロンプトで確認します。

コマンドプロンプトを開いてディレクトリはどこでもいいので以下のコマンドを実行してください。

node -v

バージョンが表示されれば完了です。

npmパッケージのインストール

次にパッケージをコマンドプロンプトからインストールします。今回はVSCodeを使用しますが、コマンドプロンプトで実行しても変わりません。

最初にディレクトリを先ほど作ったフォルダに移動してください。

まずはExpress Generatorをインストールします。先ほど作ったフォルダに移動して以下のコマンドを実行してください。

npm install -g express-generator

Express Generatorでアプリを作成します。以下コマンドを実行してください。

express -e node-app

Express Generatorを使うとExpressを使ってNode.jsでアプリケーションを作成するときに必要なモジュールが自動でインストールされます。

これだけではNodeは動かないのでnode-appのディレクトリに移動して以下のコマンドを実行してください。

npm install

ここまで来たら最低限のモジュールは用意できました。これでNode.jsが動くようになったんので、以下のコマンドでサーバを起動してください。

npm start

これはサーバを起動する合言葉のようなものです。サーバを停止するには「Ctrl」と「C」を同時に2回押します。コードを修正したときや、モジュールを新たにインストールしたときは再起動が必要なので注意が必要です。

サーバが起動しているか確認してみましょう。

http://localhost:3000/をブラウザで開いてください。

このように表示されれば成功です。

その他必要なモジュールがあるので、同じように以下のコマンドを実行してください。

npm install --save mysql

データベースのインストール

データベースをインストールします。今回はMySQLを使いますが、その中でも簡単に使えるMaria DBを使っていきます。以下のサイトを開いてください。

https://www.apachefriends.org/jp/index.html

ここからダウンロードし、インストールを完了してください。

インストールが終わったらXAMPP Control Panelを開きます。

開いたら、ApacheとMySQLを「Start」します。起動するとこのような表示になります。

このままテーブルを作っていきます。テーブルの操作は以下のURLから行うため、ブラウザでhttp://localhost/phpmyadmin/を開いてください。

開くと以下の画面が表示されます。ここからデータベースを作っていきます。開けない方は上で行った「Start」がうまくいってない可能性があるので確認してください。

データベースの作成は「新規作成」から行います。新規作成から以下のように入力して作成してください。

次にmyDataテーブルを作ります。my-nodeapp-dbデータベースから「テーブルを作成」を押してください。

各カラムは以下のように設定してください。

1234
名前idnamemailage
データ型INTVARCHARVARCHARINT
長さ/値なし100255なし

プライマリーキーの設定します。idのカラムの「A_I」のチェックボックスをチェックしてください。これはオートインクリメントのことで連番でIDを裁判してくれます。

テーブルができれば完了です。

コード実装

フォルダ構成

簡単に説明

自動でフォルダが作成されましたが、簡単にご説明します。

package.jsonはNodeの環境について記載されています。基本的には触りませんが、モジュールをインストールしたときにバージョン情報など追加されるので、確認には使えます。

app.jsはNodeが起動すると最初に実装されます。基本的にモジュールやルートの定義が記載されており、ここから各ルートが記載されているjsが呼び出されます。最初に実装されるのがapp.jsということはpackage.jsonに書かれています。

routesフォルダにはルート情報が書かれています。app.jsから呼び出されます。

viewsフォルダには表示する画面のソースがあります。HTMLも使用できますが、今回はEJSを使っています。

ファイル追加

では必要なフォルダを作成します。

「views」フォルダに以下の3つを作成してください。

  • add.ejs
  • edit.ejs
  • delete.ejs

これで必要なファイルはそろいましたので、各種ファイルを修正していきます。

routes

ルーターの役割を持つJavaScriptです。

index.js

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

var mysql_setting = {
  host: 'localhost',
  user: 'root',
  password: '',
  database: 'my-nodeapp-db'
};


//GETアクセスの処理
router.get('/', function (req, res, next) {

  //コネクションの用意
  var connection = mysql.createConnection(mysql_setting);

  //データベースに接続
  connection.connect();

  //データを取り出す
  connection.query('SELECT * from mydata',
    function (error, results, fields) {
      //データベースアクセス完了時の処理
      if (error == null) {
        var data = {
          title: 'Index',
          content: results
        };
        res.render('index', data)
      }
    });
  //接続を解除
  connection.end();
});

//新規作成ページへのアクセス
router.get('/add', (req, res, next) => {
  var data = {
    title: 'Add',
    content: '新しいレコードを入力'
  }
  res.render('add', data);
});

//新規作成フォーム送信の処理
router.post('/add', (req, res, next) => {
  var data = {
    'name': req.body.name,
    'mail': req.body.mail,
    'age': req.body.age
  };

  //データベースの設定情報
  var connection = mysql.createConnection(mysql_setting);
  //データベースに接続
  connection.connect();

  //データを登録する
  connection.query('insert into mydata set ?', data, function (error, results, fields) {
    res.redirect('/');
  });
  //接続を解除
  connection.end();
});

//指定IDのレコードを表示する
router.get('/edit', (req, res, next) => {
  var id = req.query.id;
  //データベースの設定情報
  var connection = mysql.createConnection(mysql_setting);
  //データベースに接続
  connection.connect();
  //データを取り出す
  connection.query('SELECT * from mydata where id = ?', id, function (error, results, dields) {
    //データベースアクセス完了時の処理
    if (error == null) {
      var data = {
        title: 'Edit',
        content: 'id = ' + id + 'のレコードを更新します。',
        mydata: results[0]
      }
      res.render('edit', data);
    }
  });
  //接続を解除
  connection.end();
});

//編集フォーム送信の処理
router.post('/edit', (req, res, next) => {
  var id = req.body.id;
  var data = {
    'name': req.body.name,
    'mail': req.body.mail,
    'age': req.body.age
  };
  //データベースの設定情報
  var connection = mysql.createConnection(mysql_setting);
  //データベースに接続
  connection.connect();
  //データを更新する
  connection.query('update mydata set ? where id = ?', [data, id], function (error, results, fields) {
    res.redirect('/');
  });
  //接続を解除
  connection.end();
});

//指定レコードの削除
router.get('/delete', (req, res, next) => {
  var id = req.query.id;

  //データベースの設定情報
  var connection = mysql.createConnection(mysql_setting);
  //データベースに接続
  connection.connect();
  //データを取り出す
  connection.query('SELECT * from mydata where id = ?', id, function (error, results, dields) {
    //データベースアクセス完了時の処理
    if (error == null) {
      var data = {
        title: 'Delete',
        content: 'id = ' + id + 'のレコードを削除します。',
        mydata: results[0]
      }
      res.render('delete', data);
    }
  });
  //接続を解除
  connection.end();
});

//削除フォームの送信処理
router.post('/delete', (req, res, next) => {
  var id = req.body.id;

  //データベースの設定情報
  var connection = mysql.createConnection(mysql_setting);
  //データベースに接続
  connection.connect();
  //データを削除する
  connection.query('delete from mydata where id = ?', id, function (error, results, fields) {
    res.redirect('/');
  });
  //接続を解除
  connection.end();
});

module.exports = router;

views

画面を作成するコードです。

index.ejs

一覧画面です。

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <div><a href="/add">新規作成</a></div>
    <table>
        <tr>
          <th>ID</th>
          <th>名前</th>
          <th>メール</th>
          <th>年齢</th>
          <th></th>
          <th></th>
        </tr>
      <% for(var i in content){ %>
        <tr>
            <% var obj = content[i]; %>
            <td><%= obj.id %></td>
            <td><%= obj.name %></td>
            <td><%= obj.mail %></td>
            <td><%= obj.age %></td>
            <td>
              <form action="/edit" method="get">
                <input type="hidden" name="id" value="<%= obj.id %>">
                <input type="submit" value="更新">
            </form>
            </td>
            <td>
              <form action="/delete" method="get">
                <input type="hidden" name="id" value="<%= obj.id %>">
                <input type="submit" value="削除">
              </form>
            </td>
        </tr>
        <% } %>
    </table>
  </body>
</html>

add.ejs

新規作成画面です。

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
  <head>
    <h1><%= title %></h1>
  </head>
  <div role="main">
    <p><%= content %></p>
    <form action="/add" method="post">
      <table>
        <tr>
          <th>NAME</th>
          <td><input type="text" name="name" value=""></td>
        </tr>
        <tr>
          <th>MAIL</th>
          <td><input type="text" name="mail" value=""></td>
        </tr>
        <tr>
          <th>AGE</th>
          <td><input type="number" name="age" value=""></td>
        </tr>
        <tr>
          <th></th>
          <td><input type="submit" value="送信"></td>
        </tr>
      </table>
    </form>
  </div>
</body>
</html>

edit.ejs

更新画面です。

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
  <head>
    <h1><%= title %></h1>
  </head>
  <div role="main">
    <p><%= content %></p>
    <form action="/edit" method="post">
      <input type="hidden" name="id" value="<%= mydata.id %>">
      <table>
        <tr>
          <th>NAME</th>
          <td><input type="text" name="name" value="<%= mydata.name %>"></td>
        </tr>
        <tr>
          <th>MAIL</th>
          <td><input type="text" name="mail" value="<%= mydata.mail %>"></td>
        </tr>
        <tr>
          <th>AGE</th>
          <td><input type="number" name="age" value="<%= mydata.age %>"></td>
        </tr>
        <tr>
          <th></th>
          <td><input type="submit" value="送信"></td>
        </tr>
      </table>
    </form>
  </div>
</body>

</html>

delete.ejs

削除画面です。

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
  <head>
    <h1><%= title %></h1>
  </head>
  <div role="main">
    <p><%= content %></p>
    <table>
      <tr>
        <th>NAME</th>
        <td><%= mydata.name %></td>
      </tr>
      <tr>
        <th>MAIL</th>
        <td><%= mydata.mail %></td>
      </tr>
      <tr>
        <th>AGE</th>
        <td><%= mydata.age %></td>
      </tr>
    </table>
    <form action="/delete" method="post">
      <input type="hidden" name="id" value="<%= mydata.id %>">
      <p><input type="submit" value="送信"></p>
    </form>
  </div>
</body>

</html>

画面を表示する

先ほどと同じようにサーバを起動してブラウザで開いてみてください。

まずデフォルトで一覧画面が表示されます。今回はデータを事前に入れてあります。

新規作成を押すとadd.ejsが呼び出され新規作成画面が開きます。

同じように更新、削除も画面が表示されます。

解説

基本的な動きはをご説明します。

まずユーザがURLをブラウザで入力したりフォームを送信するとサーバサイドに渡されます。サーバサイドではapp.jsが呼び出され、そこから対応したルーターが呼び出されます。

index.jsのようなルーターが呼び出された後はサーバサイドで処理が行われ、戻り値として表示したい画面のパスを返します。

画面のパスが呼び出さるとユーザの画面に表示されます。

Node.jsで一番大切なのはこのサーバサイドの処理が書かれているルーターです。

Expressを使うとgetやpostでの処理が簡単に書けるようになります。URLを入力したときやリンクを押したときは画面を表示するだめでよいのでgetを使います。

新規作成や変更、修正フォームを送信したときはデータベースの処理が必要なのでpostを使います。

おわりに

実際CRUD処理を作ってみるとサーバサイドの処理を自由に作成できるのでとても楽しかったです。Expressを使うと思ったより簡単に実装できました。サーバサイドを自分で作ると上で説明したクライアントサイドとサーバサイドのWebアプリの動き方を理解できるのでおすすめです。

他にもこの参考書ではミニ掲示版を作成しています。ミニ掲示板ではログイン機能やセッションを使っていてとてもためになりました。

他にもセッションやバリデーション、AjaxといったWebアプリケーションを作成するときに欠かせない技術についても少しずつ触れられています。他にはファイルにデータ出力やDBの汎用的なモジュールを使用しています。

またCSSやクライアントサイドのJavaScriptも実装できるので画面をさらにカスタマイズできます。CSSはpublicフォルダのstylesheetsに書きます。

今回の記事では説明できなかったのですが、これらを使うWebアプリを作成するときにできることが増えて楽しいので気になった方はNode.js 超入門[第2版]をぜひ買ってみてください。

Node.js 超入門[第3版]が出ているみたいです。

スポンサーリンク
JavaScriptNode.jsプログラミング
スポンサーリンク
この記事を書いた人

フリーランスエンジニアです。
未経験からSIer企業に入社して開発案件でプログラミングを学び27歳でフリーランスになりました。
主にHTML,CSS,JavaScript,Javaを書いています。
本を読むことが好きなのでIT以外にもいろいろ読んでいます。
好奇心旺盛でとりあえずやってみる精神。
楽しいことが生きがいで、仕事も私生活も楽しくなるように日々奮闘中。
お酒を飲みすぎないことが目標

まさきをフォローする
シェアする
まさきのエンジニア図書館
タイトルとURLをコピーしました