- DFS
- nestjs
- ๋์ ํ๋ก๊ทธ๋๋ฐ
- ๋นํธ๋ง์คํน
- ์นด์นด์ค ์ฝํ
- ๋ฐฑ์ค
- ํ๋ก๊ทธ๋๋จธ์ค
- DP
- ํธ๋ฆฌ
- ์น๋ฆฐ์ด
- BFS
- Python
- ๊ฐ์ฅ๊ฐ๊น์ด๊ณตํต์กฐ์
- ๋ฐฑ์๋ ํ๋ฆฌ์จ๋ณด๋ฉ
- ๋นํธ๋งต
- ์๊ณ ๋ฆฌ์ฆ
- golang
- ์ํฐ๋
- ์ฌ๋ผ์ด๋ฉ ์๋์ฐ
- C++
- js
- ์์ฝ๋
- ๋ค์ต์คํธ๋ผ
- LCs
- Union-Find
- ์ฌ๊ท
- ์ด๋ถํ์
- ํ๋ฆฌ์จ๋ณด๋ฉ
- ์นด์นด์ค2021
- go
- Today
- Total
Hello Ocean! ๐ผ
[gqlgen] gin.Context ์ด์ฉํ๊ธฐ ๋ณธ๋ฌธ
๋ฌธ์
gin์ graphql(gqlgen)์ router๋ก ์ฌ์ฉํ๋ ค๊ณ ํ ๋
gin.Context์ ๋ด์๋์ ๊ฐ๋ค์ด, graphql resolver์์ ์ฌ์ฉํ ์ ์๋ ctx(context.Context)์ ๋ด๊ฒจ์์ง ์์๋ค.
gin.Context์ key-value๋ก ์ ์ฅํ ๊ฐ์
resolver์ ctx.Value("key")๋ก ์ ๊ทผํด์ ์ฌ์ฉํ๊ณ ์ถ์ ์ํฉ
gqlgen ๊ณต์ ๋ฌธ์์์ ์ ๊ณตํ๋ example์ gin.Context๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋ด๋์ด ์๋ค. ๋งํฌ
ํ์ง๋ง, ์ด ๋ฐฉ๋ฒ์ context.Context์ gin.Context๋ฅผ ๊ทธ๋๋ก ๋ด๊ธฐ ๋๋ฌธ์ ๊ฐ๊ฐ์ resolver์์ ๋งค๋ฒ ์๋์ ์์ ์ ํด์ค์ผ ํ๋ค.
1. context.Context์์ gin.Context ๊บผ๋ด๊ธฐ
2. gin.Context์์ ์ํ๋ ๊ฐ ๊บผ๋ด๊ธฐ
func (r *resolver) Todo(ctx context.Context) (*Todo, error) {
gc, err := GinContextFromContext(ctx) // ๋งค๋ฒ gin.Context๋ฅผ ๊บผ๋ด๊ณ
if err != nil {
return nil, err
}
// gc์์ ํ์ํ ๊ฐ์ ๊บผ๋ด์ผ ํ๋ค
// ...
}
๊ธธ์ง ์์ ์ฝ๋๋ผ๊ณ ์๊ฐํ ์ ์์ง๋ง, ๋งค resolver์ ๋ถํ์ํ๊ฒ ์ค๋ณต๋ ์ฝ๋๊ฐ ๋ค์ด๊ฐ๊ฒ ๋๋ค.
์์ธ
๊ทธ๋ ๋ค๋ฉด ์, gqlgen resolver์ ctx์ gin.Context์ ๊ฐ์ด ๋ค์ด์์ง ์์๊ฑธ๊น?
gqlgen์์ ์ ๊ณตํ๋ gin์ ์ด์ฉํ example์ ๋ณด๋ฉด, graphql handler์ gin.Context.Request๋ฅผ ๋๊ธฐ๊ฒ ๋๊ณ
...
// Defining the Graphql handler
func graphqlHandler() gin.HandlerFunc {
// NewExecutableSchema and Config are in the generated.go file
// Resolver is in the resolver.go file
h := handler.NewDefaultServer(graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{}}))
return func(c *gin.Context) {
h.ServeHTTP(c.Writer, c.Request) // ์ฌ๊ธฐ!
}
}
...
h.ServeHTTP()์์๋, ๋๊ฒจ๋ฐ์ Request.Context() (==Request.ctx) ๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ค.
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
err := s.exec.PresentRecoveredError(r.Context(), err)
gqlErr, _ := err.(*gqlerror.Error)
resp := &graphql.Response{Errors: []*gqlerror.Error{gqlErr}}
b, _ := json.Marshal(resp)
w.WriteHeader(http.StatusUnprocessableEntity)
w.Write(b)
}
}()
r = r.WithContext(graphql.StartOperationTrace(r.Context())) // ์ฌ๊ธฐ!
transport := s.getTransport(r)
if transport == nil {
sendErrorf(w, http.StatusBadRequest, "transport not supported")
return
}
transport.Do(w, r, s.exec)
}
๊ฒฐ๊ณผ์ ์ผ๋ก,
gin.Context ์ ํ์์๋ ์๋์ ๊ฐ์ ํ๋๋ค์ด ์กด์ฌํ๊ณ
// gin.Context
type Context struct {
...
Request *http.Request
Keys map[string]any
...
}
gin.Context์ Set()์ ํตํด ์ ์ฅํ๋ ๊ฐ๋ค์ gin.Context.Keys ์ ์ ์ฅ๋๋๋ฐ
gqlgen resolver์ ๋์ด๊ฐ๋ context๋ gin.Context.Request.ctx ๋ผ์ ์ ๊ทผํ ์ ์๋ ๊ฒ์ด๋ค.
ํด๊ฒฐ๋ฐฉ์
๊ทธ๋ ๋ค๋ฉด ์ด๋ป๊ฒ ์ํ๋๋๋ก ์ฌ์ฉํ ์ ์์๊น?
gin.Context์ key-value๋ก ์ ์ฅํ ๊ฐ์
resolver์ ctx.Value("key")๋ก ์ ๊ทผํด์ ์ฌ์ฉํ๊ณ ์ถ์ ์ํฉ
1. ์ฌ์ฉํ ๊ฐ๋ค์ gin.Context.Keys๊ฐ ์๋ gin.Context.Request.ctx์ ์ ์ฅํ๊ธฐ
์ด๋ ๊ฒ ๋๋ฉด, ์ํ๋ ์ํฉ์ ์ป์ด๋ผ ์ ์์ง๋ง ๋ ๊ฐ์ง ๋จ์ ์ด ์๊ธด๋ค.
1) gin middleware์์ context์ ๊ฐ์ ์ ์ฅํ๋ ๋ก์ง์ด ๋ณต์กํด์ง๊ณ
2) ์ฌ๋ฌ ๊ฐ๋ฐ์๊ฐ ํจ๊ป ์์ ํ ๋ gin.Context.Keys๊ฐ ์๋๋ผ Request๋ด๋ถ ctx์ ๊ฐ์ ์ ์ฅํด์ผ ํ๋ค๋ ์ฌ์ค์ด ์ถฉ๋ถํ ๊ณต์ ๊ฐ ๋์ด์ผ ํ๋ค.
-> gqlgen ๊ณต์๋ฌธ์์์ ์ ๊ณตํ๋ ๋ฐฉ๋ฒ๊ณผ ๋น๊ตํด์ ์ด์ ์ด ์์
func ginMiddleware(c *gin.Context) {
ctx := c.Request.Context()
ctx = context.WithValue(ctx, key, value)
c.Request = c.Request.WithContext(ctx)
}
2. h.ServeHTTP() ์ด์ ์, gin.Context.Keys์ ์กด์ฌํ๋ ๊ฐ๋ค์ ํ ๋ฒ์ gin.Context.Request.ctx๋ก ๋ฃ์ด์ฃผ๊ธฐ
h.ServeHTTP()๋ฅผ ํธ์ถํ๊ธฐ ์ง์ ์ gin.Context.Keys์ ์กด์ฌํ๋ ๊ฐ๋ค์
ํ ๋ฒ์ gin.Context.Request.ctx๋ก ๋ฃ์ด์ฃผ๋ ๋ฐฉ๋ฒ์ด๋ค.
...
// Defining the Graphql handler
func graphqlHandler() gin.HandlerFunc {
// NewExecutableSchema and Config are in the generated.go file
// Resolver is in the resolver.go file
h := handler.NewDefaultServer(graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{}}))
return func(c *gin.Context) {
ctx := c.Request.Context()
for k, v := range c.Keys {
ctx = context.WithValue(ctx, k, v)
}
req := c.Request.WithContext(ctx)
h.ServeHTTP(c.Writer, req)
}
}
...
์ด์ ๋ฐฉ๋ฒ๋ค๊ณผ ํฌ๊ฒ ๋ค๋ฅธ์ ์ด ์๋ค๊ณ ๋๊ปด์ง ์ ์์ง๋ง ์ ์ง๋ณด์ ์ธก๋ฉด์์ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ์๊ฐํ๋ค.
ํ์ ๋ค๋ฅธ ๊ฐ๋ฐ์ ํน์ ์ด์ ํ์คํ ๋ฆฌ๋ฅผ ์์ด๋ฒ๋ฆฐ ๋น์ฌ์๊ฐ context์ ๊ฐ์ ์ถ๊ฐ๋ก ์ ์ฅํด์ผํ ์ํฉ์์ ์ ๊ฒฝ์ธ ํฌ์ธํธ๊ฐ ์ค์ด๋ค๊ธฐ ๋๋ฌธ์ด๋ค.
๊ต์ฅํ ์ฌ์ํ ๋ฌธ์ ๊ฐ์ง๋ง,
- ์ค๋ณต ์ฝ๋ ์ค์ด๊ธฐ
- ์ฌ์ด ์ ์ง๋ณด์
์ธก๋ฉด์์ ๊ณ ๋ฏผํด๋ณผ ์ ์์๋ ๋ฌธ์ ์๋ค.