はじめに
どうも!みなさんこんにちは!
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 |