emahiro/b.log

Drastically Repeat Yourself !!!!

【go】FWに頼らないオレオレroutingを実装する

goでFWに頼らず、net/http だけで簡単なWeb Serverを立てたいと思ったので作ってみた。

routing設定

まず躓いたのはroutingをどうするかということ。
net/httpパッケージを使用する場合、全てmain.goにroutingを書いてしまうことになりますが、FWの構造に則ってここはhttpリクエストをやりとりする箇所はちゃんとhandlerとしてディレクトリを用意したいと考えました。

(ginやechoを使っていたときはFW側で用意されたroutingをよしなに使ってましたが、いざ自分でroutingをかんがえると???ってなるものだなーと感じるなど(笑))

routingを設定する場合 www.gorillatoolkit.org github.com

上記のパッケージを使うのが一般的らしいということはわかっので、今回は gorilla/mux を使用。

gorilla/muxのinstall

$ dep ensure -add github.com/gorilla/mux
$ dep ensure

ディレクトリ構成

$GOPATH
  - src
    - project_root
      - main.go
      - handler/
        - main.go // ここに各種handlerを書いていく

実装

main.go

package main

import (
    "gothub/handler"

    "fmt"
    "net/http"

    "github.com/gorilla/mux"
    "github.com/labstack/gommon/log"
)

const port = "8080"

func main() {
    router := mux.NewRouter()
    router.HandleFunc("/", handler.Top)
    router.Handle("/", router)
    if err := http.ListenAndServe(fmt.Sprintf(":%s", port), router); err != nil {
        log.Fatal("err: %v", err)
    }
}

handler/main.go

package handler

import (
    "net/http"

    "fmt"

    "github.com/labstack/gommon/log"
)

func Top(w http.ResponseWriter, r *http.Request) {
    log.Debugf("request url: %s", r.URL)
    w.WriteHeader(http.StatusOK)
    fmt.Printf("%v", r.Body)
}

handlerに設定するメソッドには http.Resposewriterhttp.Request を引数に持たせることでhandlerとして登録してrequestを処理できるようになる。

動作させる

$ go run main.go

// 別shellで
$ curl -i http://localhost:8080
HTTP/1.1 200 OK
Date: Sat, 04 Nov 2017 09:27:35 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8

ちゃんとroutingが通っていることを確認

まとめ

goを使って簡易的なapiクライアントを作りたかったのですが、わざわざFWを使うほどでもないので自分で超薄いFWを作れたらなくらいのノリで書いてみましたら、結構簡単に作ることが出来ました。
FWを使っててのツラミとかはこのあたりのスライドにも書いてあるので標準の net/http パッケージを基準にapiサーバーとか構築するのに便利だと思いました。

www.slideshare.net