🙆

Express.jsのルーティング、ミドルウェア、クッキー、パラメータ、エンドポイントについて

2023/07/14に公開

Node.jsのフレームワークであるExpress.jsについて学習した内容の記録です。

app.use()

このメソッドはExpress.jsアプリケーションにミドルウェア関数を適用するために使用します。ミドルウェア関数は一連の関数であり、これらはクライアントからのリクエスト、サーバからのレスポンス、そして次のミドルウェア関数(nextと一般的に呼ばれる)にアクセスできます。app.use()は特定のパスに対してミドルウェア関数を適用するためにも使用できます。パスを指定しない場合、ミドルウェアは全てのリクエストに適用されます。以下のコードは全てのリクエストに対してリクエストの時間をログに記録するミドルウェアを適用しています。

const express = require('express');
const app = express();

app.use((req, res, next) => {
    console.log('Time:', Date.now());
    next();  // 次のミドルウェア関数に処理を移行します
});

パスを指定してミドルウェア関数を適用する例

app.use('/example', (req, res, next) => {
   console.log('Request URL:', req.originalUrl);
   next();
});

ルーティング

ルーティングはクライアントからのリクエストを適切なエンドポイント(ハンドラ関数)に送信するプロセスを指します。これはHTTPメソッド(GET、POST、PUT、DELETEなど)とURLのパスの組み合わせに基づいて行われます。以下は、ルートURL('/')へのGETリクエストに対するレスポンスを定義するコード例です。

const express = require('express');
const app = express();

app.get('/', (req, res) => {
    res.send('Hello, world!');  // ルートURLへのGETリクエストに対して 'Hello, world!' をレスポンスとして送信します
});

ミドルウェア

ミドルウェアはリクエストとレスポンスの間で動作し、様々な処理を行います。これは、リクエストとレスポンスのロギング、エラーハンドリング、データの解析とバリデーション、認証と認可、レスポンスのフォーマット設定などを行います。以下は、エラーが存在する場合にエラーメッセージをログに記録し、500のHTTPステータスコードとともにエラーメッセージをレスポンスとして送信するミドルウェアの例です。

const express = require('express');
const app = express();

app.use((err, req, res, next) => {
    console.error(err.stack);  // エラー情報をログに記録します
    res.status(500).send('Something broke!');  // 500のHTTPステータスコードとエラーメッセージをレスポンスとして送信します
});

Cookie(クッキー)

CookieはWebサイトがユーザーのブラウザに保存する小さなテキストファイルで、ユーザーに関する情報を保存するために使用されます。Express.jsでは cookie-parser ミドルウェアを使用してクッキーを解析し、その後のリクエストで使用できます。以下の例では、ユーザーの名前をクッキーに保存しています。

const express = require('express');
const cookieParser = require('cookie-parser');

const app = express();
app.use(cookieParser());

app.get('/setname', (req, res) => {
    res.cookie('username', '山田 太郎');  // 'username' という名前のクッキーに '山田 太郎' を保存します
    res.send('Username has been set in the cookies');
});

Cookie、LocalStorage、SessionStorageの違いは?

  1. Cookie
    CookieはWebサーバーとクライアント間で送信され、ユーザーのブラウザに保存される小さなテキストファイルです。Cookieはオリジン(ドメイン名、スキーム、ポート)毎に設定され、再びそのオリジンのサイトを訪れると、そのCookieの情報がサーバーに送信されます。これにより、例えばユーザーのログイン状態の保持や、ユーザー固有の設定を記録するなどの用途に使われます。一方で、Cookieはサイズが4KBまでという制限があり、大量のデータを保存するには適していません。

  2. ローカルストレージ
    ローカルストレージはWebブラウザが提供するストレージの一種で、ブラウザを閉じてもデータが永続的に保存されます。ローカルストレージはJavaScriptから直接アクセス可能で、大量のデータ(通常は5MBまで、ブラウザによりますが)を保存することができます。これにより、大量のデータをブラウザ側に保存したい場合や、永続的にデータを保持したい場合に利用されます。ただし、ローカルストレージはHTTPリクエストとは無関係で、サーバー側からは直接アクセスすることができません。

  3. セッションストレージ
    セッションストレージもWebブラウザが提供するストレージの一種ですが、ブラウザのタブやウィンドウが閉じられた時点でデータが削除される点がローカルストレージとは異なります。つまり、セッションストレージはユーザーのセッション中(ブラウザを開いている間)のみデータを保持します。ローカルストレージと同様に、セッションストレージもJavaScriptから直接アクセス可能で、大量のデータを保存することができます。

パスパラメータ、クエリパラメータ(クエリ文字列)

パスパラメータ

URLのパスの一部として含まれる値で、一般的には特定のリソースを識別するために使用されます。パスパラメータは、Expressのルーティングにおいてコロン(:)で始まる単語として定義されます。

app.get('/users/:userId', (req, res) => {
  let userId = req.params.userId;
  res.send(`User Id is: ${userId}`);
});

上記の例では、/users/:userIdというパスが定義されています。:userIdがパスパラメータで、リクエストURLが/users/123であれば、req.params.userId123を返します。

クエリパラメータ

URLの末尾に追加され、?で始まり、&で区切られる一連のキー-値のペアです。これらのパラメータは、任意の追加情報を送信するために使用されます。クエリパラメータはExpressのreq.queryオブジェクトを通じてアクセス可能です。

app.get('/search', (req, res) => {
  let searchQuery = req.query.q;
  res.send(`Search query is: ${searchQuery}`);
});

上記の例では、/search?q=expressというURLでリクエストがあった場合、req.query.qexpressを返します。

両者を組み合わせることも可能です。たとえば、ユーザーが特定のクエリで検索を行うケースを想定したルーティングを次に示します。

app.get('/users/:userId/search', (req, res) => {
  let userId = req.params.userId;
  let searchQuery = req.query.q;
  res.send(`User Id is: ${userId}. Search query is: ${searchQuery}`);
});

この例では、/users/123/search?q=expressというリクエストがあった場合、req.params.userId123を、req.query.qexpressを返します。

エンドポイント

エンドポイントはAPIが公開するURLの特定のパスで、リクエストを受け取り、適切なレスポンスを送信します。これは特定のリソース(ユーザー、商品、記事など)に関する操作を表すことが多いです。以下は、特定のユーザーIDに対応するユーザー情報を取得するためのエンドポイントの例です。

const express = require('express');
const app = express();

app.get('/user/:id', (req, res) => {
  const id = req.params.id;  // URLからユーザーIDを取得します
  res.send(`You requested user with id: ${id}`);  // 取得したユーザーIDをレスポンスとして送信します
});

Discussion