導入
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)
}
実務のプロジェクトでは、複雑なルーティング(パスパラメータやミドルウェアなど)を扱うために chi や gin のような外部ルーターライブラリを使うことも多いですが、その土台にあるのは、ここで見た net/http の考え方――「パスごとにハンドラ関数を対応させる」という基本形です。
このサイトの学習用シミュレータはネットワーク通信に対応していないため、実際にサーバーを動かすには手元の Go 環境で go run main.go を実行し、ブラウザで http://localhost:8080/hello?name=太郎 にアクセスして確認してください。