Gqlgen: how to access echo.context in resolver?

Created on 27 Jun 2019  路  3Comments  路  Source: 99designs/gqlgen

What happened?

I am using the echo framework, I used jwt for authentication. But I need to get the token in the context.Context in the resolver. How should I get the token through the context.Context?

What did you expect?

get token in resolver

Minimal graphql.schema and models to reproduce

versions

  • gqlgen version?
  • go version?
  • dep or go modules?

Most helpful comment

I took the gqlgen getting-started and followed the gin recipe, but substituting echo framework for Gin framework. I'm new to all this, so your mileage may vary.

package main

import (
    "context"
    "fmt"
    "github.com/labstack/echo/v4"
    "github.com/labstack/echo/v4/middleware"
    "net/http"
    "github.com/99designs/gqlgen/handler"

)

func main() {
    // Echo instance
    e := echo.New()
    graphqlHandler := handler.GraphQL(NewExecutableSchema(Config{Resolvers: &Resolver{}}))
    playgroundHandler := handler.Playground("GraphQL", "/query")

    // Middleware
    e.Use(Process)
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())

    // Route => handler
    e.GET("/", func(c echo.Context) error {
        cc := c.(*CustomContext)
        return cc.String(http.StatusOK, "Hello, World!\n")
    })
    e.POST("/query", func(c echo.Context) error {
        cc := c.(*CustomContext)
        req := cc.Request()
        res := cc.Response()
        graphqlHandler.ServeHTTP(res, req)
        return nil
    })

    e.GET("/playground", func(c echo.Context) error {
        cc := c.(*CustomContext)
        req := cc.Request()
        res := cc.Response()
        playgroundHandler.ServeHTTP(res, req)
        return nil
    })

    // Start server
    e.Logger.Fatal(e.Start(":1323"))
}

type CustomContext struct {
    echo.Context
    ctx    context.Context
}

func (c *CustomContext) Foo() {
    println("foo")
}

func (c *CustomContext) Bar() {
    println("bar")
}

func EchoContextFromContext(ctx context.Context) (*echo.Context, error) {
    echoContext := ctx.Value("EchoContextKey")
    if echoContext == nil {
        err := fmt.Errorf("could not retrieve echo.Context")
        return nil, err
    }

    ec, ok := echoContext.(*echo.Context)
    if !ok {
        err := fmt.Errorf("echo.Context has wrong type")
        return nil, err
    }
    return ec, nil
}

// Process is the middleware function.
func Process(next echo.HandlerFunc) echo.HandlerFunc {
    return func(c echo.Context) error {
        ctx := context.WithValue(c.Request().Context(), "EchoContextKey", c)
        c.SetRequest(c.Request().WithContext(ctx))

        cc := &CustomContext{c, ctx}

        return next(cc)
    }
}

All 3 comments

there is a receipe for gin.Context. echo might work similarly:
https://gqlgen.com/recipes/gin/

thanks

I took the gqlgen getting-started and followed the gin recipe, but substituting echo framework for Gin framework. I'm new to all this, so your mileage may vary.

package main

import (
    "context"
    "fmt"
    "github.com/labstack/echo/v4"
    "github.com/labstack/echo/v4/middleware"
    "net/http"
    "github.com/99designs/gqlgen/handler"

)

func main() {
    // Echo instance
    e := echo.New()
    graphqlHandler := handler.GraphQL(NewExecutableSchema(Config{Resolvers: &Resolver{}}))
    playgroundHandler := handler.Playground("GraphQL", "/query")

    // Middleware
    e.Use(Process)
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())

    // Route => handler
    e.GET("/", func(c echo.Context) error {
        cc := c.(*CustomContext)
        return cc.String(http.StatusOK, "Hello, World!\n")
    })
    e.POST("/query", func(c echo.Context) error {
        cc := c.(*CustomContext)
        req := cc.Request()
        res := cc.Response()
        graphqlHandler.ServeHTTP(res, req)
        return nil
    })

    e.GET("/playground", func(c echo.Context) error {
        cc := c.(*CustomContext)
        req := cc.Request()
        res := cc.Response()
        playgroundHandler.ServeHTTP(res, req)
        return nil
    })

    // Start server
    e.Logger.Fatal(e.Start(":1323"))
}

type CustomContext struct {
    echo.Context
    ctx    context.Context
}

func (c *CustomContext) Foo() {
    println("foo")
}

func (c *CustomContext) Bar() {
    println("bar")
}

func EchoContextFromContext(ctx context.Context) (*echo.Context, error) {
    echoContext := ctx.Value("EchoContextKey")
    if echoContext == nil {
        err := fmt.Errorf("could not retrieve echo.Context")
        return nil, err
    }

    ec, ok := echoContext.(*echo.Context)
    if !ok {
        err := fmt.Errorf("echo.Context has wrong type")
        return nil, err
    }
    return ec, nil
}

// Process is the middleware function.
func Process(next echo.HandlerFunc) echo.HandlerFunc {
    return func(c echo.Context) error {
        ctx := context.WithValue(c.Request().Context(), "EchoContextKey", c)
        c.SetRequest(c.Request().WithContext(ctx))

        cc := &CustomContext{c, ctx}

        return next(cc)
    }
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

RobertoOrtis picture RobertoOrtis  路  3Comments

jacksontj picture jacksontj  路  4Comments

cemremengu picture cemremengu  路  3Comments

steebchen picture steebchen  路  3Comments

andrewmunro picture andrewmunro  路  4Comments