とあるWeb屋の備忘録

とあるWeb屋の備忘録。たまに雑記。

Express基礎

復習しながら自分用にmdでメモってましたがせっかくなので備忘録としてこちらに残します。
2018.11月からB2BSaaSに転職したことでNode.jsを書く機会があるのでNodeの学習を再開しました。
前に学習していたときから時間が空いて色々忘れている部分も多かったのでexpress-generatorの雛形+過去に自分が書いた記事を見て復習中です。

Node.jsについて書いた過去のエントリはこちら



Express自体

ルーティングとミドルウェアのWebフレームワーク
Expressはリクエストが来たら上から評価される

Expressアプリケーション

一連のミドルウェア関数呼び出し
(連続してミドルウェア関数を呼び出すことで成り立っている)

ミドルウェア関数

以下の3つ所有

  • requestオブジェクト
  • responseオブジェクト
  • request-responseサイクルにおける次のミドルウェア関数に対するアクセス権
    次のミドルウェア関数nextという変数名であらわされる

実行できる4つのタスク

  • 任意のコードを実行
  • requestオブジェクト、responseオブジェクトを変更
  • request-responseサイクルを終了する
  • スタック内の次のミドルウェアを呼び出す
    ※現在のミドルウェア関数がrequest-responseサイクルを終了しない場合はnext()を使って次のミドルウェア関数に制御を渡さなければならない。そうしないとrequestはハングしたままになりガーベジコレクションの対象にならない

Expressアプリケーションで使用できる4タイプのミドルウェア


アプリケーション・レベルのミドルウェアについて

以下の例はapp.use()を使って/ミドルウェアをマウントしている
* /ミドルウェアのサブスタックが形成されたことになる
* /のパスは設定しなくてもよくて、設定しない場合はアプリケーションがリクエストを受け取るたびに実行される
* next('route')を使うことで次のルートに制御を渡している
※app.use()だとnext('route')使えないので注意する(app.METHOD()もしくはrouter.METHOD()で使用可能)

/* GET home page. */
app.get('/', function (req, res, next) {
  if (req.params.id === undefined) {
    next('route')
  }else {
    next()
  }
}, function (req, res, next) {
  res.render('index', { title: 'Express02' });
})

app.get('/', function (req, res, next) {
  res.render('index', { title: 'Express' });
})

エラー処理ミドルウェアについて

  • 引数は(err, req, res, next)の4つでなければいけない
  • 他のapp.use()とroutes呼び出し後に定義する(最後に定義するということ)
  • エラーハンドリング用にapp.use()を使ってエラー処理関数を定義する
  • エラー処理関数でnextを呼ばないときはレスポンスを記述する必要がある
    next(err)を呼び出した時点で、エラー処理関数だけ実行され他のミドルウェア関数は実行されない


エラーを発生させる

var createError = require('http-errors');を使ってエラーを発生させる

エラーコードは以下ページ参照

https://www.npmjs.com/package/http-errors

app.use('/', function(req, res, next) {
  next(createError(404));
});

app.use(function(err, req, res, next) {
  console.log(err) // NotFoundError: Not Found
  console.log(err.message) // Not Found
  console.log(err.status) // 404

  // request-responseサイクルのローカル変数(res.locals)はクライアントにレスポンスを返すまで参照することができる
  // req.app.get('env')で環境を検出
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  //レスポンスのステータスコードを指定
  res.status(err.status || 500);
  res.render('error');
});


また、express-generatorの雛形のapp.jsのソースを色々調べて備忘録コメント残したものが以下です。

// Create HTTP errors for Express, Koa, Connect, etc. with ease.
var createError = require('http-errors');
// The path module provides utilities for working with file and directory paths
var path = require('path');

var express = require('express'); 
var cookieParser = require('cookie-parser'); // サード・パーティー・ミドルウェア
var logger = require('morgan'); // HTTP request logger middleware for node.js. サード・パーティー・ミドルウェア

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
console.log(__dirname) // D:\localhost\node\www

app.use(logger('dev')); // ログの出力フォーマットを指定
app.use(express.json()); // This is a built-in middleware function in Express. It parses incoming requests with JSON payloads and is based on body-parser.JSONペイロードで受信したリクエストを解析する
app.use(express.urlencoded({ extended: false })); // This is a built-in middleware function in Express. It parses incoming requests with urlencoded payloads and is based on body-parser.URLエンコードされたペイロードで受信したリクエストを解析する
app.use(express.static(path.join(__dirname, 'public'))); // This is a built-in middleware function in Express. It serves static files and is based on serve-static.HTMLファイルや画像などの静的リソースを提供する
app.use(cookieParser());

app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

以下のサイトを参考にさせていただきました。

Express - Node.js web application framework

ミドルウェアの使用 | Express 入門 | CODE Q&A 問題解決 [日本語]

逆引きメモ:expressの使い方 - Qiita

一通り復習が終わったらVue+Nodeで何かwebアプリを作りはじめたいと思います。
ここまで読んでいただいてありがとうございました!!