Feedback on gqlgen echo recipe


#1

I’m new to echo, and I’m trying to port the gqlgen gin recipe to the echo framework. I need to translate between the echo.context and the context.Context.

Any feedback on the following approach would be very welcome!

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)
	}
}