🔩 ねじき教室 Go と Web の教室

最小の Web サーバー

読了目安 約2分

net/http で最小の Web サーバーを書き、ページ内の REST クライアントからリクエストを送ります。

30秒でつかむ ListenAndServeが、ハンドラを待ち受けさせる
ListenAndServeが、ハンドラを待ち受けさせるサーバーが待ち受け、届いたリクエストをハンドラに渡し、書かれたレスポンスを返します。1待ち受けListenAndServe2ハンドラリクエストを処理3返事ResponseWriter
  1. 待ち受け ListenAndServe
  2. ハンドラ リクエストを処理
  3. 返事 ResponseWriter
この章の目次

Part 2 で外から観察したレスポンスを、今度は返す側として自分の手で書きます。 使うのは標準ライブラリ net/http だけです。

サーバーを書いて起動する

Go
package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
		log.Printf("INFO request: %s %s", r.Method, r.URL.Path)
		fmt.Fprintln(w, "Hello, ねじき教室!")
	})
	http.ListenAndServe(":8080", nil)
}

この章のオンライン実行環境にはRESTクライアントが付属しています。 HTTPサーバーのコードを入れたGoエディタの「▶ 実行」を押すと、サーバーを起動し、リクエストを待機出来ます。

下のクライアントでメソッドにGET、エンドポイントに/hello を設定しリクエストを送ってください。レスポンスに Hello, ねじき教室!、サーバーログに INFO request: GET /hello が出れば成功です。

本来、サーバーを動かすには手元に Go を入れ、ターミナルから起動する必要があります。この教室では最初の仕組みをすぐ試せるよう、ページ内でだけサーバーを動かせるようにしています。

手元でも試したくなったら、学習環境を整えるを終えてから、同じコードを実行してください。コード中の :8080 は、そのときにサーバーが待ち受けるポートの番号です。

手元で curl を使って試す

まず一つ目のターミナルで、サーバーを起動します。ターミナルは止まったように見えますが、リクエストを待っている正常な状態です。

シェル
go run main.go

次に別のターミナルで curl を実行します。ブラウザで http://localhost:8080/hello を開いても同じです。

シェル
curl http://localhost:8080/hello

localhost は「このマシン自身」を指すホスト名です。

コードを読む

http.HandleFunc は、「このパスにリクエストが来たら、この関数を呼べ」という対応を登録します。 リクエストを受け取ってレスポンスを作る関数をハンドラと呼びます。

fmt.Fprintlnfmt.Println の書き込み先を選べる版です。 ここでは w、つまりレスポンスに書き込んでいます。

http.ListenAndServe(":8080", nil) がサーバーの本体です。 wr、第 2 引数 nil の正体は次章で読みます。

リクエストごとに goroutine が走っている

net/http のサーバーは、リクエストごとに新しい goroutine を起動し、その上でハンドラを実行します。 この仕組みは goroutine と並行性で見たとおりです。

複数のリクエストが同時に来ても、それぞれを待たせず処理できるようになっています。実際に並行して届く場面は、後のアプリケーション作成で扱います。

試してみよう:URI を /hello 以外に変えて送信し、404 になることを確かめてください。 たとえば /bye に変えると、こう表示されます。

テキスト
404 Not Found
404 page not found

404 page not found は、登録のないパスに対して net/http が自動で返すレスポンスです。