本文へスキップ
BecomeCoder

Goコース · 第8章 実務のGo · レッスン33

net/http でHTTPサーバー ― ハンドラとルーティング

ローカル実施

導入

Go の代表的な用途がサーバーサイド開発です。標準ライブラリの net/http だけで、外部フレームワークなしにHTTPサーバーを立てられます。まずは最小構成を見てみましょう。

説明

package main

import (
	"fmt"
	"net/http"
)

// "/hello" へのリクエストを処理するハンドラ関数
func helloHandler(w http.ResponseWriter, r *http.Request) {
	name := r.URL.Query().Get("name")
	if name == "" {
		name = "ゲスト"
	}
	fmt.Fprintf(w, "こんにちは、%sさん", name)
}

func main() {
	http.HandleFunc("/hello", helloHandler)

	fmt.Println("サーバーを起動しました: http://localhost:8080")
	http.ListenAndServe(":8080", nil)
}
  • ハンドラ関数func(w http.ResponseWriter, r *http.Request) という決まった形を持ちます。w に書き込んだ内容がレスポンスになり、r からリクエストの情報(URLクエリパラメータ・ヘッダーなど)を読み取れます。
  • http.HandleFunc("/hello", helloHandler) … パス "/hello" へのリクエストが来たら helloHandler を呼ぶ、というルーティングの登録。
  • http.ListenAndServe(":8080", nil) … 8080番ポートでサーバーを起動し、リクエストを待ち受け続けます。

構造体を使ってJSONを返すAPIも、net/http と前レッスンの encoding/json を組み合わせれば書けます。

type User struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

func userHandler(w http.ResponseWriter, r *http.Request) {
	u := User{Name: "田中", Age: 30}
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(u)
}

複数のエンドポイントを整理するときは、パスごとに http.HandleFunc を並べていきます。

func main() {
	http.HandleFunc("/users", listUsersHandler)
	http.HandleFunc("/users/create", createUserHandler)
	http.ListenAndServe(":8080", nil)
}

実務のプロジェクトでは、複雑なルーティング(パスパラメータやミドルウェアなど)を扱うために chigin のような外部ルーターライブラリを使うことも多いですが、その土台にあるのは、ここで見た net/http の考え方――「パスごとにハンドラ関数を対応させる」という基本形です。

このサイトの学習用シミュレータはネットワーク通信に対応していないため、実際にサーバーを動かすには手元の Go 環境で go run main.go を実行し、ブラウザで http://localhost:8080/hello?name=太郎 にアクセスして確認してください。