Skip to content

Commit a83885e

Browse files
authored
Merge pull request #365 from ut-code/combine-http-and-express
expressの章を改定
2 parents 3aebc3f + 2d5652b commit a83885e

3 files changed

Lines changed: 84 additions & 10 deletions

File tree

130 KB
Loading
126 KB
Loading

docs/3-web-servers/05-template-engine/index.md

Lines changed: 84 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
11
---
2-
title: Express とテンプレートエンジン
2+
title: Express によるサーバー構築
33
---
44

55
import CodeBlock from '@theme/CodeBlock';
66
import Term from "@site/src/components/Term";
77
import ViewSource from "@site/src/components/ViewSource";
88

9-
## Express パッケージを用いて HTTP サーバーを構築する
9+
## ウェブサイトが動作する仕組み
1010

11-
[Express パッケージ](https://www.npmjs.com/package/express) を用いると、Node.js 標準の `http` モジュールよりも簡単に Web サーバーを構築できます。
11+
[「Web プログラミングの基礎を学ぼう」](../../1-trial-session/index.md) の章では、ウェブサイトを表示するために HTML ファイルと JavaScript ファイルを作成し、ブラウザから開きました。しかしながら、通常のウェブサイトではこのような手順は踏まず、URL をブラウザに入力することにより閲覧することができます。
12+
13+
Web では、通常インターネットを介してデータをやり取りします。インターネットを人間が直接利用することはできないので、何らかのコンピューターを使用しなければなりません。このとき、通常は
14+
15+
- **クライアント**: サービスを利用する側のコンピューターや、その上で直接通信を担うソフトウェア
16+
- **サーバー**: サービスを提供する側のコンピューターや、その上で直接通信を担うソフトウェア
17+
18+
という二者の関係が発生します。また、その間で発生する通信を、その方向により
19+
20+
- **リクエスト**: クライアントからサーバーに対する要求
21+
- **レスポンス**: リクエストに対する応答
22+
23+
のように区別して呼びます。それでは、Node.js で Web サーバーを作ってみましょう。
24+
25+
## Express パッケージを用いて Web サーバーを構築する
26+
27+
[Express パッケージ](https://www.npmjs.com/package/express) を用いると、簡単に Web サーバーを構築できます。
1228

1329
まずは `express` パッケージを npm でインストールします。
1430

@@ -23,18 +39,72 @@ const express = require("express");
2339
const app = express();
2440

2541
app.get("/", (request, response) => {
26-
response.send("Hello Express");
42+
response.send("Hello World");
2743
});
2844

2945
app.listen(3000);
3046
```
3147

32-
`main.js` を起動することにより、 `http://localhost:3000/``Hello Express` が表示されます。
48+
ファイルを保存したら、作成したファイルを実行し、ブラウザで `http://localhost:3000/` にアクセスしてみましょう。ブラウザに `Hello World` と表示されましたか?
49+
50+
![HTTPサーバー](./http-server.png)
51+
52+
:::caution Web サーバーの停止
53+
54+
このプログラムは、一度起動すると停止しません。サーバーにとって、クライアントからのリクエストはいつやってくるかわからないため、常に起動し続けている必要があるからです。Node.js プログラムを終了するには、ターミナル上で `Ctrl + C` を押します。
55+
56+
:::
57+
58+
書いたコードを詳しく見てみましょう。
59+
60+
まず、`require("express")` の戻り値は関数となっており、この関数を呼び出すことにより、[`express.Application`](https://expressjs.com/ja/api.html#app) クラスのインスタンスが作成されます。
61+
62+
[`express.Application#get` メソッド](https://expressjs.com/ja/api.html#app.get.method)は、クライアントから特定のパスに対してリクエストが来た時に実行される関数を追加するメソッドです。第 1 引数にはパスの文字列を、第 2 引数には実行される関数を指定します。
63+
64+
例えば今回であれば第 1 引数に `"/path"` を渡すと `http://localhost:3000/path` にリクエストが来たときに関数が実行されることになります。
65+
66+
第 2 引数の関数を詳しく見てみましょう。この関数は2つの引数をとります。具体的には第 1 引数に受け取ったリクエストを表す [`express.Request` クラス](https://expressjs.com/ja/api.html#req) のインスタンスが、第 2 引数にこれから送るレスポンスを表す [`express.Response` クラス](https://expressjs.com/ja/api.html#res) のインスタンスが渡されます。
67+
68+
そして [`express.Response#send` メソッド](https://expressjs.com/ja/api.html#res.send)により、クライアントが必要なデータを送信することができます。
69+
70+
:::tip `http`標準<Term type="javascriptModule">モジュール</Term>
71+
`express` を使わずに Node.js 単体 で Web サーバーを作成するには、`http` 標準<Term type="javascriptModule">モジュール</Term>を使用します。
72+
73+
`http` 標準モジュールを使って 簡単な Web サーバーを構築すると以下のようなコードになります。
74+
75+
```javascript title=main.js
76+
const http = require("http");
77+
78+
const server = new http.Server();
79+
80+
server.addListener("request", (request, response) => {
81+
response.write("Hello World");
82+
response.end();
83+
});
84+
85+
server.listen(3000);
86+
```
87+
88+
[`http.Server` クラス](https://nodejs.org/api/http.html#class-httpserver) は、サーバーを作成するためのクラスです。このクラスの [`addListener` メソッド](https://nodejs.org/api/events.html#emitteraddlistenereventname-listener) は、イベントハンドラを追加するためのメソッドです。第 1 引数にイベントの名前、第 2 引数にイベントハンドラとなる関数オブジェクトを指定します。
89+
90+
[`request` イベント](https://nodejs.org/api/http.html#event-request) は、クライアントからリクエストが来るたびに発生するイベントです。イベントハンドラの第 1 引数に受け取ったリクエストを表す [`http.IncomingMessage` クラス](https://nodejs.org/api/http.html#class-httpincomingmessage) のインスタンスが、第 2 引数にこれから送るレスポンスを表す [`http.ServerResponse` クラス](https://nodejs.org/api/http.html#class-httpserverresponse) のインスタンスが渡されます。
3391

34-
[前頁](../04-http-server/index.md)`http` 標準モジュールを用いた例とほとんど同じことを行うプログラムになっていますが、`express` を使う場合は少々異なる部分があります。まず、`require("express")` の戻り値は関数となっており、この関数を呼び出すことにより、[`express.Application`](https://expressjs.com/ja/api.html#app) クラスのインスタンスが作成されます
92+
`express` パッケージと比較してみましょう
3593

3694
[`express.Application#get` メソッド](https://expressjs.com/ja/api.html#app.get.method)は、`http` 標準モジュールにおける `request` イベントハンドラの登録に相当する操作を行うためのメソッドです。イベントハンドラの引数に `request``response` が存在する点では一致していますが、Express では [`express.Response#send` メソッド](https://expressjs.com/ja/api.html#res.send)が利用できます。これは、[`http.ServerResponse#write`](https://nodejs.org/api/http.html#responsewritechunk-encoding-callback) メソッドと、[`http.ServerResponse#end`](https://nodejs.org/api/http.html#responseenddata-encoding-callback) メソッドを順番に呼ぶ操作に対応します。
3795

96+
:::
97+
98+
## HTTP
99+
100+
インターネット上には、さまざまなデータが流れています。インターネットに接続しているコンピューターが好き勝手にデータを送受信しても、意味のあるやり取りは成立しません。このため、通信を行うための手順を標準化しておく必要があります。こうしてできた手順のことを、**プロトコル**と呼びます。
101+
102+
Web の世界で用いられるプロトコルは、通常 **HTTP** と呼ばれるものです。ブラウザに `http://example.com/path/to/index.html` が入力された場合、ブラウザとサーバーの間で次の図のような通信が行われます。
103+
104+
![HTTP](./basic-http.png)
105+
106+
Web サーバーにアクセスするために用いた http://localhost:3000/ のうち、http はプロトコルを、localhost:3000 はサーバーの所在地を表しています (localhost は自分のコンピューターを指します)。
107+
38108
## 静的ホスティング
39109

40110
次の例では、`/``/script.js``/sub/``/sub/script.js` へのリクエストについて、それぞれファイルから読み込んでレスポンスを送信しています。
@@ -82,7 +152,7 @@ app.listen(3000);
82152

83153
:::
84154

85-
## EJS テンプレートエンジン
155+
## 動的なウェブページ
86156

87157
前項のプログラムを書き換えて、複雑な HTML を出力できるようにしてみましょう。
88158

@@ -121,9 +191,11 @@ console.log(["Apple", "Banana", "Orange"].join("/")); // Apple/Banana/Orange
121191

122192
:::
123193

124-
なかなか大変なことになっています。これから HTML がもっと長くなったり、さらに複雑なプログラムが必要になってきたらこのまま続けていくのは難しそうです
194+
このようにテンプレートリテラルを用いることで、JavaScript のプログラムから HTML に変更を加え出力することができます
125195

126-
[EJS](https://ejs.co/) をはじめとした**テンプレートエンジン**は、プログラミング言語から HTML などを作成する作業を簡単にしてくれます。`ejs` パッケージを npm でインストールしてください。先ほどのプログラムを、EJS を用いて書き換えると、次のようになります。
196+
:::tip テンプレートエンジン
197+
上記のようにテンプレートリテラルを使って HTML を生成することもできますが、HTML がもっと長くなったり、さらに複雑なプログラムが必要になってきたらこのまま続けていくのは難しそうです。
198+
[EJS](https://ejs.co/) をはじめとした**テンプレートエンジン**は、プログラミング言語から HTML などを作成する作業を簡単にしてくれます。先ほどのプログラムを、EJS を用いて書き換えると、次のようになります。(手元で試したい場合は ejs をインストールしてください)
127199

128200
```javascript title=main.js
129201
const fs = require("fs");
@@ -168,10 +240,12 @@ app.listen(3000);
168240

169241
テンプレート内の `<%` から `%>` で囲まれた部分は、JavaScript のプログラムとして実行されます。また、`<%=` から `%>` で囲まれた部分は JavaScript の式として評価され、最終的な結果に埋め込まれます。
170242

243+
:::
244+
171245
## 課題
172246

173247
- Express を用いて、`あなたは n 人目のお客様です。` とレスポンスする Web サーバーを作成してください。`n` はアクセスされるたびに 1 ずつ増えるようにしてください。
174-
- 上記プログラムに EJS を追加してみてください。
248+
- (発展) 上記プログラムに EJS を追加してみてください。
175249
- (重要) アクセスされた時刻をウェブサーバー側で求めて表示するウェブサーバーと、ブラウザに求めさせるウェブサーバーをそれぞれ作成してください。
176250
- この 2 つの違いは何でしょうか。どういった場合にどちらの手法を使うのが適切でしょうか。
177251

0 commit comments

Comments
 (0)