0
0

More than 3 years have passed since last update.

【Go】web サーバーの作成方法が様々あるのでまとめる

Last updated at Posted at 2020-08-22

※注意: この記事ははあくまで個人学習用に整理しただけの記事で、内容としては不完全なものになります。読んでも参考にならない可能性が高いです。

go を学習していて、Web サーバーの作成方法がいくつもあったので、自分の整理用にまとめる。

パターンその1

handler というハンドラ関数を定義

  • http.HandleFunc を使用
  • index という handler 関数を別で定義し、http.HandleFunc の第二引数に関数を渡す
  • 最後に http.ListenAndServe 実行
package main


import (
    "fmt"
    "net/http"
)

func index(writer http.ResponseWriter, request *http.Request) {
    // 省略
}

func main() {
    http.HandleFunc("/", index)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal("ListenAndServe:", err)
    }
}

パターンその2

templateHandler、独自のハンドラを作成

  • http.Handle を使用
  • 最後に http.ListenAndServe 実行
package main

import (
    "html/template"
    "net/http"
)

type templateHandler struct {
    once synce.Once
    filename string
    templ *template.Template
}
func (t *templateHander) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    t.once.Do(func() {
        t.templ = template.Must(template.ParseFiles(filepath.Join("templates", t.filename)))
    })
    t.templ.Execute(w, nil)
}

func main() {
    http.Handle("/", &templateHandler{filename: "index.html"})

    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal("ListenAndServe:", err)
    }
}

templates/index.html

<html>
  <head>
    <title>index</title>
  </head>
  <body>
    <div>index</div>
  </body>
</html>

パターンその3

templateHandler、独自のハンドラを作成

  • http.NewServeMux() で mux(マルチプレクサ)を作成
  • mux.HandleFunc に URL パターンと index handler 関数を渡す
  • http.Server 構造体のポインタで初期化。その際に Handler field に mux を渡す
  • 初期化したものを server 変数へ代入
  • 最後に server の ListenAndServe メソッドを実行
package main

import (
    "net/http"
    "time"
)

func index(writer http.ResponseWriter, request *http.Request) {
    // 省略
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/", index)
    server := &http.Server{
        Addr:           config.Address,
        Handler:        mux,
        ReadTimeout:    time.Duration(config.ReadTimeout * int64(time.Second)),
        WriteTimeout:   time.Duration(config.WriteTimeout * int64(time.Second)),
        MaxHeaderBytes: 1 << 20,
    }
    server.ListenAndServe()
}

http.Server という構造体は以下のようになっている
https://golang.org/src/net/http/server.go?h=ListenAndServe#L2520

type Server struct {
    Addr            string
    Handler         Handler // handler to invoke, http.DefaultServeMux if nil
    TLSConfig       *tls.Config
    ReadTimeout     time.Duration
    ReadHeaderTimeout   time.Duration
    WriteTimeout        time.Duration
    IdleTimeout     time.Duration
    MaxHeaderBytes      int
    TLSNextProto        map[string]func(*Server, *tls.Conn, Handler)
    ConnState       func(net.Conn, ConnState)
    ErrorLog        *log.Logger
    BaseContext     func(net.Listener) context.Context
    ConnContext     func(ctx context.Context, c net.Conn) context.Context
    inShutdown      atomicBool
    disableKeepAlives   int32
    nextProtoOnce       sync.Once
    nextProtoErr        error
    mu          sync.Mutex
    listeners       map[*net.Listener]struct{}
    activeConn      map[*conn]struct{}
    doneChan        chan struct{}
    onShutdown      []func()
}

Server struct の Handler field に http.NewServeMux() で作成したマルチプレクサを登録しているようだ。

他にもパターンを発見したら随時更新していく。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0