nautilus/gateway

Override Introspection Request

krisanalfa opened this issue · 1 comments

Hi, can I override introspection request. For example adding extra HTTP headers. I've tried to use custom QueryerFactory, but it does not work. QueryerFactory only works on Query scope, not when introspection happens.

package main

import (
	"net"
	"net/http"
	"os"
	"time"

	"github.com/nautilus/gateway"
	"github.com/nautilus/graphql"
)

type AddHeaderTransport struct {
	T http.RoundTripper
}

func (adt *AddHeaderTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	req.Header.Add("X-Gateway-Introspection", "true")

	return adt.T.RoundTrip(req)
}

func NewAddHeaderTransport(T http.RoundTripper) *AddHeaderTransport {
	return &AddHeaderTransport{T}
}

func main() {
	schemas, err := graphql.IntrospectRemoteSchemas(
		"http://localhost:4030/graphql",
	)
	if err != nil {
		panic(err)
	}

	httpClient := &http.Client{
		Timeout: time.Second * 10,
		Transport: NewAddHeaderTransport(&http.Transport{
			Dial: (&net.Dialer{
				Timeout: 5 * time.Second,
			}).Dial,
			TLSHandshakeTimeout: 5 * time.Second,
		}),
	}

	factory := gateway.QueryerFactory(func(ctx *gateway.PlanningContext, url string) graphql.Queryer {
		return graphql.NewSingleRequestQueryer(url).WithHTTPClient(httpClient)
	})

	gw, err := gateway.New(
		schemas,
		gateway.WithQueryerFactory(&factory),
	)
	if err != nil {
		panic(err)
	}

	if os.Getenv("GO_ENV") != "production" {
		http.HandleFunc("/graphql", gw.PlaygroundHandler)
	}

	err = http.ListenAndServe(":3000", nil)
	if err != nil {
		panic(err)
	}
}

Found the answer, turns out I need to create my own IntrospectRemoteSchemas

// IntrospectRemoteSchema is something
func IntrospectRemoteSchema(url string, client *http.Client) (*graphql.RemoteSchema, error) {
	schema, err := graphql.IntrospectAPI(graphql.NewSingleRequestQueryer(url).WithHTTPClient(client))
	if err != nil {
		return nil, err
	}

	return &graphql.RemoteSchema{
		URL:    url,
		Schema: schema,
	}, nil
}

// IntrospectRemoteSchemas is something
func IntrospectRemoteSchemas(urls []string, client *http.Client) ([]*graphql.RemoteSchema, error) {
	// build up the list of remote schemas
	schemas := []*graphql.RemoteSchema{}

	for _, service := range urls {
		// introspect the locations
		schema, err := IntrospectRemoteSchema(service, client)
		if err != nil {
			return nil, err
		}

		// add the schema to the list
		schemas = append(schemas, schema)
	}

	return schemas, nil
}

// Somewhere in main()
schemas, err := IntrospectRemoteSchemas(*&[]string{"http://localhost:5030/graphql"}, &http.Client{
	Timeout: time.Second * 10,
	Transport: &http.Transport{
		Dial: (&net.Dialer{
			Timeout: 5 * time.Second,
		}).Dial,
		TLSHandshakeTimeout: 5 * time.Second,
	},
})