株式会社エスロジカル
株式会社エスロジカル
SSL証明書(DV、OV、EV)、セキュリティ、Web開発、Linux開発、Go言語

HOME > 技術ドキュメント > Go 言語 Web アプリ入門

Go 言語 Web アプリ入門


Go 言語(Golang)は、シンプルさと高いパフォーマンスを両立した Web バックエンド開発に適した言語です。
標準ライブラリ net/http だけで高速な HTTP サーバーを構築できます。
本ドキュメントでは、HTTP サーバーの基本から JSON REST API、PostgreSQL 接続、 本番運用(systemd + Nginx)までを解説します。


# 公式サイトから最新版をダウンロード(バージョンは適宜確認)
wget https://go.dev/dl/go1.22.3.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.22.3.linux-amd64.tar.gz

# PATH に追加(~/.bashrc または ~/.profile)
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc

# バージョン確認
go version
# go version go1.22.3 linux/amd64

Go の標準ライブラリだけで動く最小構成の HTTP サーバーです。

// main.go
package main

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

func helloHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Hello, World!")
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", helloHandler)

    log.Println("Listening on :8080")
    log.Fatal(http.ListenAndServe(":8080", mux))
}
go run main.go
# ブラウザで http://localhost:8080/ を開く

JSON を返す REST API の基本構成です。

package main

import (
    "encoding/json"
    "log"
    "net/http"
    "time"
)

type HealthResponse struct {
    Status string `json:"status"`
    Time   string `json:"time"`
}

func writeJSON(w http.ResponseWriter, status int, v any) {
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(status)
    json.NewEncoder(w).Encode(v)
}

func healthHandler(w http.ResponseWriter, r *http.Request) {
    writeJSON(w, http.StatusOK, HealthResponse{
        Status: "ok",
        Time:   time.Now().Format(time.RFC3339),
    })
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("GET /health", healthHandler)

    log.Println("Listening on :8080")
    log.Fatal(http.ListenAndServe(":8080", mux))
}

Go 1.22 以降、mux.HandleFunc("GET /path", ...) のようにメソッドとパスをまとめて指定できます。


// ロギングミドルウェア
func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Printf("%s %s %s", r.RemoteAddr, r.Method, r.URL)
        next.ServeHTTP(w, r)
    })
}

// CORS ミドルウェア
func corsMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "*")
        w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
        w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
        if r.Method == http.MethodOptions {
            w.WriteHeader(http.StatusNoContent)
            return
        }
        next.ServeHTTP(w, r)
    })
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("GET /health", healthHandler)

    // ミドルウェアをチェーン
    handler := loggingMiddleware(corsMiddleware(mux))
    log.Fatal(http.ListenAndServe(":8080", handler))
}

go mod init myapp
go get github.com/lib/pq
import (
    "database/sql"
    "log"
    _ "github.com/lib/pq"
)

func connectDB() *sql.DB {
    dsn := "host=localhost port=5432 user=myuser password=mypass dbname=mydb sslmode=disable"
    db, err := sql.Open("postgres", dsn)
    if err != nil {
        log.Fatal(err)
    }
    db.SetMaxOpenConns(25)
    db.SetMaxIdleConns(5)
    return db
}

# 本番用ビルド(バイナリ単体で動作)
GOOS=linux GOARCH=amd64 go build -o /opt/myapp/server .

# /etc/systemd/system/myapp.service を作成
[Unit]
Description=My Go Web App
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/server
Restart=always
RestartSec=5
Environment=PORT=8080

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
sudo systemctl status myapp

Nginx をリバースプロキシとして前段に置く構成は Nginx SSL/TLS 設定 をご参照ください。


本番環境では Go アプリを直接 HTTPS で動かすより、 前段の Nginx に SSL証明書を設定してリバースプロキシする構成が一般的です。
SSL証明書が必要な場合は エスロジカルの SSL証明書販売 をご利用ください。 DV 証明書(RapidSSL)3,960円/1年(税込)〜、審査サポート・インストール代行あり。

Go アプリ自体で直接 TLS を終端する場合は http.ListenAndServeTLS が使えます:

log.Fatal(http.ListenAndServeTLS(":443",
    "/etc/ssl/certs/your_domain.crt",
    "/etc/ssl/private/your_domain.key",
    mux,
))

← 技術ドキュメント一覧へ戻る