うさぎ小屋(仮)

📅  2021-11-23

graphQLサーバーにgorilla/muxでミドルウェアを導入する


gqlgenで作成したgraphqlサーバーは素のnet/httpを利用していましたが、

このままだとmiddlewareの実装が大変なので、gorilla/muxに置き換えてcors対策や認証のmiddleware実装の準備をしていきます。

https://gqlgen.com/recipes/authentication/

gqlgenのドキュメントではgo-chi/chiが使われているのですが、gollira/muxのほうがメジャーである感じがするのでgollira/muxにしました。

https://github.com/gorilla/mux

まずはルートディレクトリにある ./server.go を移動します。

server.go -> cmd/graphql/main.go

今後起動コマンドは以下になります。

go run ./cmd/graphql/main.go

次にgollira/muxを導入していきます。

go get -u github.com/gorilla/mux

cmd/graphql/main.goの修正してmuxを適用

@@ -9,6 +9,7 @@ import (
        "github.com/99designs/gqlgen/graphql/playground"
        "github.com/amasok/sample-graphql/app/presentation/graphql"
        "github.com/amasok/sample-graphql/app/presentation/graphql/generated"
+       "github.com/gorilla/mux"
 )

 const defaultPort = "8080"
@@ -19,11 +20,13 @@ func main() {
                port = defaultPort
        }

+       r := mux.NewRouter()
+
        srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graphql.Resolver{}}))

-       http.Handle("/", playground.Handler("GraphQL playground", "/query"))
-       http.Handle("/query", srv)
+       r.Handle("/", playground.Handler("GraphQL playground", "/query"))
+       r.Handle("/query", srv)

        log.Printf("connect to http://localhost:%s/ for GraphQL playground", port)
-       log.Fatal(http.ListenAndServe(":"+port, nil))
+       log.Fatal(http.ListenAndServe(":"+port, r))
 }

認証は少し重たいので、corsのmiddleware実装を試しに実装してみます。

app/middleware/cors.goの実装

package middleware

import "net/http"

// TODO: configでoriginを切り分けられるようにする
func CORSForGraphql(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		origin := "localhost:8080"
		w.Header().Set("Access-Control-Allow-Origin", origin)
		if r.Method == http.MethodOptions {
			w.Header().Set("Access-Control-Allow-Methods", "POST")
		}
		next.ServeHTTP(w, r)
	})
}

cmd/graphql/main.goでcorsのmiddlewareを適用する

				r := mux.NewRouter()
+       r.Use(middleware.CORSForGraphql) # <-これを追加するだけ

この状態でplaygraoundのネットワークを確認するとAccess-Control-Allow-Originがレスポンスヘッダーにのって返ってくることが確認できる。

image in the content
$ curl http://localhost:8080 -X OPTIONS  -I
HTTP/1.1 200 OK
Access-Control-Allow-Methods: POST
Access-Control-Allow-Origin: localhost:8080
Content-Type: text/html
Date: Sun, 21 Nov 2021 03:25:15 GMT
Content-Length: 1643


$ curl http://localhost:8080 -X POST  -I
HTTP/1.1 200 OK
Access-Control-Allow-Origin: localhost:8080
Content-Type: text/html
Date: Sun, 21 Nov 2021 03:25:33 GMT
Content-Length: 1643

ミドルウェアの基盤はできたので次は認証認可を入れていきたい。