LoginSignup
28
29

Express.js完全入門

Last updated at Posted at 2023-04-13

Express.jsとは

Express.jsは、Node.jsのための軽量で柔軟なWebアプリケーションフレームワークです。
Express.jsを使用すると、Node.jsを使用してWebアプリケーションを作成するための様々な機能を簡単に実装できます。

MVCアーキテクチャを採用し、ルーティング、テンプレートエンジン、ミドルウェア、セッション、Cookieの処理、静的ファイルの提供、データベースの操作など、Webアプリケーション開発に必要な基本的な機能を提供しています。
また、豊富なサードパーティーモジュールを使用することで、より高度な機能を追加することも可能です。

Express.jsの使い方

事前準備

Node.jsをインストールし、npmを使用できる環境を作っておく必要があります。

確認コマンド
>node -v
v14.16.0

>npm -v
6.14.11

環境構築

1. プロジェクトの作成

新しいディレクトリを作成し、そのディレクトリでnpmプロジェクトを初期化します。

プロジェクト作成コマンド
>mkdir my-express-project

>cd my-express-project

>npm init --yes
Wrote to C:\【path】\my-express-project\package.json:

{
  "name": "my-express-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

2. Express.jsのインストール

npmを使用して、以下のコマンドを実行してExpress.jsをインストールします。

Express.jsインストールコマンド
>npm install express

+ express@4.18.2
added 57 packages from 42 contributors and audited 57 packages in 2.353s

7 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

3. サーバーの作成

index.js ファイルを作成して、以下コードを作成します。

index.js
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.listen(3000, () => {
  console.log('Server listening on port 3000');
});

package.json にstartコマンドを追加します。

package.json
{
  "name": "my-express-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.2"
  }
}

動作確認

1. サーバ起動

以下のコマンドを実行してサーバを起動します。

サーバ起動コマンド
>npm start

> my-express-project@1.0.0 start C:\【path】\my-express-project
> node index.js

Server listening on port 3000

2. サーバ確認

curl コマンドを使用してサーバの実行を確認します。

curlコマンド
>curl http://localhost:3000
Hello World!

3. サーバ停止

ctrl + c でサーバを停止できます。
(Macでは control + c

ルーティング

Express.jsにおけるルーティングとは、HTTPリクエストのURLに応じて、アプリケーション内で実行する処理を決定する仕組みです。ルーティングは、HTTPメソッド(GET、POST、PUT、DELETEなど)とURLパターンによって定義されます。

Express.jsでは、app.【HTTPメソッド名】() 関数を使用してルートを定義します。
app.get()app.post()app.put()app.delete() などのHTTPメソッドに対応した関数を使用することができます。

以下は、GETリクエストのルートを定義する例です。

GETリクエストのルート定義例
app.get('/', function (req, res) {
  res.send('Hello World!')
})

上記の例では、ルートに対するGETリクエストを定義しています。
ルートに対するリクエストが発生した場合、第2引数に指定されたコールバック関数が呼び出されます。
この関数内で、レスポンスを返すための処理を行います。
各コールバック関数の第1引数 req はリクエストオブジェクト、第2引数 res はレスポンスオブジェクトです。

また、URLパラメータを使用して、動的なルートを定義することもできます。

動的なルート定義例
app.get('/users/:id', function (req, res) {
  res.send('User ID: ' + req.params.id)
})

この例では、/users/:id というパスを定義しています。
:id はURLパラメータで、リクエストURLに含まれる任意の文字列にマッチします。
このURLパラメータは、req.params オブジェクトを介して取得することができます。

また、複数のハンドラ関数を使用して、ルートに対する処理を定義することもできます。

複数のハンドラ関数を使用したルート定義例
app.get('/users/:id', function (req, res, next) {
  // ミドルウェアの処理
  next()
}, function (req, res) {
  res.send('User ID: ' + req.params.id)
})

この例では、2つのハンドラ関数を使用しています。
最初のハンドラ関数は、リクエストに対するミドルウェアの処理を行います。
このミドルウェアの処理が完了した後、次のハンドラ関数が実行され、レスポンスが返されます。

Express.jsのルーティングを用いてREST APIを実装することができます。

REST APIとは

REST (Representational State Transfer) APIは、Webサービスを開発するためのアーキテクチャスタイルの1つで、HTTPプロトコルを使用してWeb上でのデータのやりとりを行うための方法論です。

REST APIでは、リソースを一意の識別子(URI)によって表現し、HTTPメソッド(GET、POST、PUT、DELETEなど)を使用してリソースに対して操作を行います。

HTTPメソッド 操作
GET リソースを取得する
POST リソースを作成する
PUT 指定したIDのリソースを更新する
DELETE 指定したIDのリソースを削除する

REST API実装

index.js を以下のように修正すると、 GET, POST, PUT, DELETE のHTTPメソッドを使用してリクエストを処理するようにできます。

index.js
const express = require('express');
const app = express();

// GETリクエスト
app.get('/', (req, res) => {
  res.send({
    msg:'GET request'
  });
});

// POSTリクエスト
app.post('/', (req, res) => {
  res.send({
    msg:'POST request'
  });
});

// PUTリクエスト
app.put('/:id', (req, res) => {
  res.send({
    id: req.params.id,
    msg:'PUT request'
  });
});

// DELETEリクエスト
app.delete('/:id', (req, res) => {
  res.send({
    id: req.params.id,
    msg:'DELETE request'
  });
});

app.listen(3000, () => {
  console.log('Server started on port 3000');
});

curl コマンドを使用してサーバの実行を確認できます。

curlコマンド
>curl -X GET http://localhost:3000/
{"msg":"GET request"}
>curl -X POST http://localhost:3000/
{"msg":"POST request"}        
>curl -X PUT http://localhost:3000/123
{"id":"123","msg":"PUT request"}
>curl -X DELETE http://localhost:3000/123
{"id":"123","msg":"DELETE request"}

ミドルウェア

Express.jsにおけるミドルウェアとは、HTTPリクエストとレスポンスの間に挟まる処理を指します。
ミドルウェアは、アプリケーション全体で共通の処理や、特定のルートで実行する必要がある処理などに使用されます。

Express.jsでは、app.use() 関数を使用してミドルウェアを登録します。
登録されたミドルウェアは、HTTPリクエストが発生するたびに呼び出されます。
ミドルウェアの実装方法は、以下のようになります。

ミドルウェア実装
// ミドルウェアの実装
const myMiddleware = function(req, res, next) {
  // ミドルウェアの処理
  next(); // 次のミドルウェアへ処理を移す
};

// ミドルウェアの登録
app.use(myMiddleware);

このように、app.use() 関数に登録するミドルウェア関数には、reqresnext という3つの引数が渡されます。
req はリクエストオブジェクト、res はレスポンスオブジェクト、next は次のミドルウェア関数へ処理を移すための関数です。

ミドルウェア実装

index.js を以下のように修正すると、 HTTPリクエストのメソッドとURLをログに出力するようにできます。

index.js
const express = require('express');
const app = express();

const loggerMiddleware = function(req, res, next) {
  console.log(`[${new Date()}] ${req.method} ${req.url}`);
  next();
};

app.use(loggerMiddleware);

// GETリクエスト
app.get('/', (req, res) => {
  res.send({
    msg:'GET request'
  });
});

// POSTリクエスト
app.post('/', (req, res) => {
  res.send({
    msg:'POST request'
  });
});

// PUTリクエスト
app.put('/:id', (req, res) => {
  res.send({
    id: req.params.id,
    msg:'PUT request'
  });
});

// DELETEリクエスト
app.delete('/:id', (req, res) => {
  res.send({
    id: req.params.id,
    msg:'DELETE request'
  });
});

app.listen(3000, () => {
  console.log('Server started on port 3000');
});

curl コマンドを使用してサーバの実行を確認できます。

curlコマンド
>curl -X GET http://localhost:3000/
{"msg":"GET request"}
>curl -X POST http://localhost:3000/
{"msg":"POST request"}        
>curl -X PUT http://localhost:3000/123
{"id":"123","msg":"PUT request"}
>curl -X DELETE http://localhost:3000/123
{"id":"123","msg":"DELETE request"}

上記コマンド実行時にサーバ側のコンソールで以下のログが表示されます。

コンソール
[Sun Mar 19 2023 01:42:24 GMT+0900 (日本標準時)] GET /
[Sun Mar 19 2023 01:42:29 GMT+0900 (日本標準時)] POST /
[Sun Mar 19 2023 01:42:34 GMT+0900 (日本標準時)] PUT /123
[Sun Mar 19 2023 01:42:39 GMT+0900 (日本標準時)] DELETE /123

静的ファイル

Webアプリケーションでは、静的ファイル(画像、CSS、JavaScriptなど)を扱うことが一般的です。

以下では、Express.jsで静的ファイルを扱う方法について解説します。

静的ファイルの配置場所を指定する

まず、静的ファイルが配置されている場所を指定する必要があります。
Express.jsでは、express.static ミドルウェアを使用して、静的ファイルのディレクトリを指定できます。

例えば、以下のように記述することで、publicディレクトリ内の静的ファイルを使用できます。

app.use(express.static('public'))

ルーティングの設定による静的ファイルの提供

ルーティングを設定して、public/imagesディレクトリ内のファイルを提供しています。

optionsオブジェクトには、ファイル送信時の設定が含まれています。

fileNameには、リクエストパラメータのファイル名が格納されます。

app.get('/images/:filename', function(req, res) {
  var options = {
    root: __dirname + '/public/images/',
    dotfiles: 'deny',
    headers: {
      'x-timestamp': Date.now(),
      'x-sent': true
    }
  };

  var fileName = req.params.filename;
  res.sendFile(fileName, options, function (err) {
    if (err) {
      next(err);
    } else {
      console.log('Sent:', fileName);
    }
  });
});

この例では、/images/:filenameというパスに対して、public/imagesディレクトリ内のファイルを提供するルーティングを設定しています。

optionsオブジェクトには、ファイル送信時の設定が含まれています。

rootには、ファイルのルートディレクトリを指定します。

dotfilesには、ドットで始まるファイルの扱い方を指定します。

この例では、denyを指定して、ドットで始まるファイルを送信しないようにしています。

headersには、レスポンスヘッダーを指定します。この例では、x-timestampとx-sentを指定しています。

fileNameには、リクエストパラメータのファイル名が格納されます。res.sendFileメソッドを使用して、ファイルを送信します。

送信が完了したら、コールバック関数が実行されます。エラーが発生した場合は、next関数にエラーを渡します。

静的ファイルのキャッシュ

Express.jsでは、静的ファイルのキャッシュ機能を提供しています。キャッシュを使用することで、同じファイルに対して複数のリクエストがあった場合でも、サーバーからのレスポンス時間を短縮することができます。

キャッシュを有効化するには、maxAgeオプションを使用します。以下は、キャッシュを有効化する例です。

app.use(express.static('public', { maxAge: 86400000 }));

maxAgeには、キャッシュの有効期限をミリ秒単位で指定します。上記の例では、1日間キャッシュを有効化しています。

キャッシュを有効化することで、同じファイルに対して複数回のリクエストがあった場合でも、サーバーからのレスポンス時間を短縮することができます。

ただし、キャッシュ期間が長すぎると、ファイルの変更が反映されない場合があるので、適切な期間を設定する必要があります。

静的ファイルの実装

index.js を以下のように修正すると、 /test-image パスにアクセスして public/images/test.png が返却するようにできます。

index.js
const express = require('express');
const app = express();
const path = require('path');

const loggerMiddleware = function(req, res, next) {
  console.log(`[${new Date()}] ${req.method} ${req.url}`);
  next();
};

app.use(loggerMiddleware);

// 静的ファイルの提供とキャッシュの有効化
app.use(express.static('public', { maxAge: 86400000 }));

// test-imageリクエスト
app.get('/test-image', (req, res) => {
  res.sendFile(path.join(__dirname, 'public/images/test.png'));
});

// GETリクエスト
app.get('/', (req, res) => {
  res.send({
    msg:'GET request'
  });
});

// POSTリクエスト
app.post('/', (req, res) => {
  res.send({
    msg:'POST request'
  });
});

// PUTリクエスト
app.put('/:id', (req, res) => {
  res.send({
    id: req.params.id,
    msg:'PUT request'
  });
});

// DELETEリクエスト
app.delete('/:id', (req, res) => {
  res.send({
    id: req.params.id,
    msg:'DELETE request'
  });
});

app.listen(3000, () => {
  console.log('Server started on port 3000');
});

このコードでは、/test-imageパスにアクセスするとpublic/images/test.pngが返却されます。

path.join(__dirname, 'public/images/test.png')を使用して、現在のディレクトリからの相対パスでファイルを指定しています。

localhost:3000/test-imageにアクセスしてサーバの実行を確認できます。

image.png

GitHub

今回の記事で紹介したソースコードをGitHubで公開しています。

28
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
29