18
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

OthloTechAdvent Calendar 2018

Day 17

net/httpとfasthttpの対応表

Last updated at Posted at 2018-12-17

はじめに

どうも!みなさんこんにちは!
Go言語楽しんでますか?

最近,Go言語を使ったとあるインターンに参加したのですが,
そこでnet/httpに取って代わるかもしれない
fasthttpというパケージに触れる機会があったので,
今回は対応表という形でまとめたいと思います.

fasthttpとは

go言語でHTTP通信を行うためのライブラリです.

go言語の標準パッケージではnet/httpがすでに用意されているのですが,
fasthttpでは標準パッケージを凌駕する処理の速さで一時期有名になりました.
公式のベンチマークでは,従来に比べ10倍の差がでたようです.

fasthttpのインストール
go get -u github.com/valyala/fasthttp

対応表

サーバの起動

net/http

net/http
package main

import (
	"fmt"
	"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello net/http!!")
}

func main() {
	// "/"に対しての処理
	http.HandleFunc("/", handler)

	// 8080でサーバを起動
	http.ListenAndServe(":8080", nil)
}

fasthttp

fasthttp
package main

import (
	"fmt"
	"github.com/valyala/fasthttp"
)

func handler(ctx *fasthttp.RequestCtx) {
	fmt.Fprint("Hello fasthttp!!")
}

func main() {
	requestHandler := func(ctx *fasthttp.RequestCtx) {
		// ctx.Path()がnet/httpでいうr.URL.Pathにあたる
		switch string(ctx.Path()) {
		// "/"に対しての処理
		case "/":
			handler(ctx)
		default:
			ctx.Error("Unsupported path", fasthttp.StatusNotFound)
		}
	}
	// 8080でサーバを起動
	fasthttp.ListenAndServe(":8080", requestHandler)
}

エラーハンドリング

net/http

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

fasthttp

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

クエリ

以下のURLのクエリからそれぞれの値を取得
http://localhost:8080?name=satto&age=24

net/http

net/http
func handler(w http.ResponseWriter, r *http.Request) {
	// クエリはr.URL.Query().Get("key")で取得可能
	name := r.URL.Query().Get("name")
	age := r.URL.Query().Get("age")
	fmt.Fprintf(w, "name: %s age: %s\n", name, age)
}

/*===============省略==================*/

fasthttp

fasthttp
func handler(ctx *fasthttp.RequestCtx) {
	// クエリはctx.QueryArgs().Peek("key")で取得可能
	// stringでアスキーコードを文字に変換
	name := string(ctx.QueryArgs().Peek("name"))
	age := string(ctx.QueryArgs().Peek("age"))
	fmt.Fprintf(ctx, "name: %s age: %s\n", name, age)
}

/*===============省略==================*/

POST

JSONをPOSTするとJSONが返ってくる簡単なAPIサーバ

net/http

net/http
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

type Input struct {
	In string
}

type Output struct {
	Out string
}

func jsonHandleFunc(w http.ResponseWriter, r *http.Request) {
	// outputの用意
	output := Output{"( ・`ω・´)"}
	outjson, err := json.Marshal(output)
	if err != nil {
		fmt.Println(err)
	}
	w.Header().Set("Content-Type", "application/json")
	fmt.Fprint(w, string(outjson))

	// POSTされたときの処理
	// ボディーの中身をチェック
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		output.Out = err.Error()
		fmt.Println(err.Error())
		return
	}
	input := Input{}
	// bodyの中身(JSON)をinputに流し込む
	err = json.Unmarshal(body, &input)
	if err != nil {
		output.Out = err.Error()
		fmt.Println(err.Error())
		return
	}
}

func main() {
	// 例 localhost:8080/json にJSONをPOSTするとJSONが返ってくる
	http.HandleFunc("/json", jsonHandleFunc)

	// 8080でサーバを起動
	http.ListenAndServe(":8080", nil)
}

fasthttp

fasthttp
package main

import (
	"encoding/json"
	"fmt"
	"github.com/valyala/fasthttp"
)

type Input struct {
	In string
}

type Output struct {
	Out string
}

func jsonHandleFunc(ctx *fasthttp.RequestCtx) {
	// outputの用意
	output := Output{"( ・`ω・´)"}
	// output用のJSON作成
	outjson, err := json.Marshal(output)
	if err != nil {
		fmt.Println(err)
	}
	ctx.Response.Header.Set("Content-Type", "application/json")
	fmt.Fprint(ctx, string(outjson))

	// POSTされたときの処理
	// ボディーの中身を取得
	body := ctx.PostBody()
	input := Input{}
	// bodyの中身(JSON)をinputに流し込む
	err = json.Unmarshal(body, &input)
	if err != nil {
		output.Out = err.Error()
		fmt.Println(err.Error())
		return
	}
}

func main() {
	requestHandler := func(ctx *fasthttp.RequestCtx) {
		switch string(ctx.Path()) {
		// 例 localhost:8080/json にJSONをPOSTするとJSONが返ってくる
		case "/json":
			jsonHandleFunc(ctx)
		default:
			ctx.Error("Unsupported path", fasthttp.StatusNotFound)
		}
	}
	// 8080でサーバを起動
	fasthttp.ListenAndServe(":8080", requestHandler)
}

実際にcurlで叩いてみる

$ curl -H "Content-type: application/json" -X POST -d '{"In": "(´・ω・`)"}' http://localhost:8080/json

結果

$ {"Out":"( ・`ω・´)"}

静的ファイル配信

ディレクトリ構造

.
├── main.go
└── static
    └── index.html

http://localhost:8080 にアクセスするとstaticディレクトリのindex.htmlの内容が表示される

net/http

net/http
package main

import (
	"net/http"
)

func main() {
	// 静的ファイル配信
	// カレントディレクトリにあるstaticの中身を配信
	http.Handle("/", http.FileServer(http.Dir("static")))

	// 8080でサーバを起動
	http.ListenAndServe(":8080", nil)
}

fasthttp

fasthttp
package main

import (
	"github.com/valyala/fasthttp"
)

func main() {
	// fsは静的ファイルを配信するために必要な設定を表す
	var fs fasthttp.FS
	requestHandler := func(ctx *fasthttp.RequestCtx) {
		switch string(ctx.Path()) {
		case "/":
			// カレントディレクトリにあるstaticのindex.htmlを配信
			fs = fasthttp.FS{
				Root: "./static",
				// ファイルを指定してあげないと読み込まれない
				IndexNames: []string{"index.html"},
			}
		default:
			ctx.Error("Unsupported path", fasthttp.StatusNotFound)
		}
		// 静的ファイルを配信するためのリクエストハンドラを作成
		fsHandler := fs.NewRequestHandler()
		fsHandler(ctx)
	}
	// 8080でサーバを起動
	fasthttp.ListenAndServe(":8080", requestHandler)
}

ステータスコード

ほとんど変わりません

ステータスコード fasthttp net/http
100 fasthttp.StatusContinue http.StatusContinue
101 fasthttp.StatusSwitchingProtocols http.StatusSwitchingProtocols
102 fasthttp.StatusProcessing http.StatusProcessing
200 fasthttp.StatusOK http.StatusOK
201 fasthttp.StatusCreated http.StatusCreated
202 fasthttp.StatusAccepted http.StatusAccepted
203 fasthttp.StatusNonAuthoritativeInfo http.StatusNonAuthoritativeInfo
204 fasthttp.StatusNoContent http.StatusNoContent
205 fasthttp.StatusResetContent http.StatusResetContent
206 fasthttp.StatusPartialContent http.StatusPartialContent
207 fasthttp.StatusMultiStatus http.StatusMultiStatus
208 fasthttp.StatusAlreadyReported http.StatusAlreadyReported
226 fasthttp.StatusIMUsed http.StatusIMUsed
300 fasthttp.StatusMultipleChoices http.StatusMultipleChoices
301 fasthttp.StatusMovedPermanently http.StatusMovedPermanently
302 fasthttp.StatusFound http.StatusFound
303 fasthttp.StatusSeeOther http.StatusSeeOther
304 fasthttp.StatusNotModified http.StatusNotModified
305 fasthttp.StatusUseProxy http.StatusUseProxy
306 fasthttp._
307 fasthttp.StatusTemporaryRedirect http.StatusTemporaryRedirect
308 fasthttp.StatusPermanentRedirect http.StatusPermanentRedirect
400 fasthttp.StatusBadRequest http.StatusBadRequest
401 fasthttp.StatusUnauthorized http.StatusUnauthorized
402 fasthttp.StatusPaymentRequired http.StatusPaymentRequired
403 fasthttp.StatusForbidden http.StatusForbidden
404 fasthttp.StatusNotFound http.StatusNotFound
405 fasthttp.StatusMethodNotAllowed http.StatusMethodNotAllowed
406 fasthttp.StatusNotAcceptable http.StatusNotAcceptable
407 fasthttp.StatusProxyAuthRequired http.StatusProxyAuthRequired
408 fasthttp.StatusRequestTimeout http.StatusRequestTimeout
409 fasthttp.StatusConflict http.StatusConflict
410 fasthttp.StatusGone http.StatusGone
411 fasthttp.StatusLengthRequired http.StatusLengthRequired
412 fasthttp.StatusPreconditionFailed http.StatusPreconditionFailed
413 fasthttp.StatusRequestEntityTooLarge http.StatusRequestEntityTooLarge
414 fasthttp.StatusRequestURITooLong http.StatusRequestURITooLong
415 fasthttp.StatusUnsupportedMediaType http.StatusUnsupportedMediaType
416 fasthttp.StatusRequestedRangeNotSatisfiable http.StatusRequestedRangeNotSatisfiable
417 fasthttp.StatusExpectationFailed http.StatusExpectationFailed
418 fasthttp.StatusTeapot http.StatusTeapot
422 fasthttp.StatusUnprocessableEntity http.StatusUnprocessableEntity
423 fasthttp.StatusLocked http.StatusLocked
424 fasthttp.StatusFailedDependency http.StatusFailedDependency
426 fasthttp.StatusUpgradeRequired http.StatusUpgradeRequired
428 fasthttp.StatusPreconditionRequired http.StatusPreconditionRequired
429 fasthttp.StatusTooManyRequests http.StatusTooManyRequests
431 fasthttp.StatusRequestHeaderFieldsTooLarge http.StatusRequestHeaderFieldsTooLarge
451 fasthttp.StatusUnavailableForLegalReasons http.StatusUnavailableForLegalReasons
500 fasthttp.StatusInternalServerError http.StatusInternalServerError
501 fasthttp.StatusNotImplemented http.StatusNotImplemented
502 fasthttp.StatusBadGateway http.StatusBadGateway
503 fasthttp.StatusServiceUnavailable http.StatusServiceUnavailable
504 fasthttp.StatusGatewayTimeout http.StatusGatewayTimeout
505 fasthttp.StatusHTTPVersionNotSupported http.StatusHTTPVersionNotSupported
506 fasthttp.StatusVariantAlsoNegotiates http.StatusVariantAlsoNegotiates
507 fasthttp.StatusInsufficientStorage http.StatusInsufficientStorage
508 fasthttp.StatusLoopDetected http.StatusLoopDetected
510 fasthttp.StatusNotExtended http.StatusNotExtended
511 fasthttp.StatusNetworkAuthenticationRequired http.StatusNetworkAuthenticationRequired
18
11
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
18
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?