gateway

package module
v0.3.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 4, 2023 License: MIT Imports: 21 Imported by: 15

README

nautilus/gateway CI Checks Coverage Status Go Report Card Go Reference

A library and standalone service that composes your GraphQL APIs into one endpoint.

For a guide to getting started read this post. For full documentation visit the gateway homepage.

Running the Executable

The simplest way to run a gateway is to download an executable for your operating system from the latest release on GitHub and then run it directly on your machine:

$ ./gateway start --port 4000 --services http://localhost:3000,http://localhost:3001

Note: Instead of ./gateway, use the file path to the release you downloaded. macOS users should use the darwin release file.

For more information on possible arguments to pass the executable, run ./gateway --help.

Build from source

Alternatively, install it with the go command to your Go bin and run it:

$ go install github.com/nautilus/gateway/cmd/gateway@latest
$ gateway start --port 4000 --services http://localhost:3000,http://localhost:3001

This will start a server on port 4000 that wraps over the services running at http://localhost:3000 and http://localhost:3001.

For more information on possible arguments to pass the executable, run gateway --help.

Versioning

This project is built as a go module and follows the practices outlined in the spec. Please consider all APIs experimental and subject to change until v1 has been released at which point semantic versioning will be strictly followed. Before then, minor version bumps denote an API breaking change.

Currently supports Go Modules using Go 1.16 and above.

Documentation

Index

Constants

View Source
const MessageMissingCachedQuery = "PersistedQueryNotFound"

MessageMissingCachedQuery is the string that the server sends when the user assumes that the server knows about a caches query plan

Variables

This section is empty.

Functions

This section is empty.

Types

type AutomaticQueryPlanCache added in v0.0.15

type AutomaticQueryPlanCache struct {
	// contains filtered or unexported fields
}

AutomaticQueryPlanCache is a QueryPlanCache that will use the hash if it points to a known query plan, otherwise it will compute the plan and save it for later, to be referenced by the designated hash.

func NewAutomaticQueryPlanCache added in v0.0.15

func NewAutomaticQueryPlanCache() *AutomaticQueryPlanCache

NewAutomaticQueryPlanCache returns a fresh instance of

func (*AutomaticQueryPlanCache) Retrieve added in v0.0.15

func (c *AutomaticQueryPlanCache) Retrieve(ctx *PlanningContext, hash *string, planner QueryPlanner) (QueryPlanList, error)

Retrieve follows the "automatic query persistence" technique. If the hash is known, it will use the referenced query plan. If the hash is not know but the query is provided, it will compute the plan, return it, and save it for later use. If the hash is not known and the query is not provided, it will return with an error prompting the client to provide the hash and query

func (*AutomaticQueryPlanCache) WithCacheTTL added in v0.0.15

func (c *AutomaticQueryPlanCache) WithCacheTTL(duration time.Duration) *AutomaticQueryPlanCache

WithCacheTTL updates and returns the cache with the new cache lifetime. Queries that haven't been used in that long are cleaned up on the next query.

type DefaultLogger added in v0.1.10

type DefaultLogger struct {
	// contains filtered or unexported fields
}

DefaultLogger handles the logging in the gateway library

func (*DefaultLogger) Debug added in v0.1.10

func (l *DefaultLogger) Debug(args ...interface{})

Debug should be used for any logging that would be useful for debugging

func (*DefaultLogger) Info added in v0.1.10

func (l *DefaultLogger) Info(args ...interface{})

Info should be used for any logging that doesn't necessarily need attention but is nice to see by default

func (*DefaultLogger) QueryPlanStep added in v0.1.10

func (l *DefaultLogger) QueryPlanStep(step *QueryPlanStep)

QueryPlanStep formats and logs a query plan step for human consumption

func (*DefaultLogger) Warn added in v0.1.10

func (l *DefaultLogger) Warn(args ...interface{})

Warn should be used for logging that needs attention

func (*DefaultLogger) WithFields added in v0.1.10

func (l *DefaultLogger) WithFields(fields LoggerFields) Logger

WithFields adds the provided fields to the Log

type ErrExecutor

type ErrExecutor struct {
	Error error
}

ErrExecutor always returnes the internal error.

func (*ErrExecutor) Execute

func (e *ErrExecutor) Execute(_ *ExecutionContext) (map[string]interface{}, error)

Execute returns the internet error

type ExecutionContext added in v0.0.3

type ExecutionContext struct {
	Plan               *QueryPlan
	Variables          map[string]interface{}
	RequestContext     context.Context
	RequestMiddlewares []graphql.NetworkMiddleware
	// contains filtered or unexported fields
}

ExecutionContext is a well-type alternative to context.Context and provides the context for a particular execution.

type ExecutionMiddleware added in v0.0.3

type ExecutionMiddleware interface {
	ExecutionMiddleware()
}

ExecutionMiddleware are things that interject in the execution process

type Executor

type Executor interface {
	Execute(ctx *ExecutionContext) (map[string]interface{}, error)
}

Executor is responsible for executing a query plan against the remote schemas and returning the result

type ExecutorFunc

type ExecutorFunc func(ctx *ExecutionContext) (map[string]interface{}, error)

ExecutorFunc wraps a function to be used as an executor.

func (ExecutorFunc) Execute

func (e ExecutorFunc) Execute(ctx *ExecutionContext) (map[string]interface{}, error)

Execute invokes and returns the internal function

type FieldURLMap

type FieldURLMap map[string][]string

FieldURLMap holds the intformation for retrieving the valid locations one can find the value for the field

func (FieldURLMap) Concat

func (m FieldURLMap) Concat(other FieldURLMap) FieldURLMap

Concat returns a new field map url whose entries are the union of both maps

func (FieldURLMap) RegisterURL

func (m FieldURLMap) RegisterURL(parent string, field string, locations ...string)

RegisterURL adds a new location to the list of possible places to find the value for parent.field

func (FieldURLMap) URLFor

func (m FieldURLMap) URLFor(parent string, field string) ([]string, error)

URLFor returns the list of locations one can find parent.field.

type Gateway

type Gateway struct {
	// contains filtered or unexported fields
}

Gateway is the top level entry for interacting with a gateway. It is responsible for merging a list of remote schemas into one, generating a query plan to execute based on an incoming request, and following that plan

func New

func New(sources []*graphql.RemoteSchema, configs ...Option) (*Gateway, error)

New instantiates a new schema with the required stuffs.

func (*Gateway) Execute

func (g *Gateway) Execute(ctx *RequestContext, plans QueryPlanList) (map[string]interface{}, error)

Execute takes a query string, executes it, and returns the response

func (*Gateway) GetPlans added in v0.1.0

func (g *Gateway) GetPlans(ctx *RequestContext) (QueryPlanList, error)

func (*Gateway) GraphQLHandler

func (g *Gateway) GraphQLHandler(w http.ResponseWriter, r *http.Request)

GraphQLHandler returns a http.HandlerFunc that should be used as the primary endpoint for the gateway API. The endpoint will respond to queries on both GET and POST requests. POST requests can either be a single object with { query, variables, operationName } or a list of that object.

func (*Gateway) PlaygroundHandler

func (g *Gateway) PlaygroundHandler(w http.ResponseWriter, r *http.Request)

PlaygroundHandler returns a combined UI and API http.HandlerFunc. On POST requests, executes the designated query. On all other requests, shows the user an interface that they can use to interact with the API.

func (*Gateway) Query added in v0.0.5

func (g *Gateway) Query(ctx context.Context, input *graphql.QueryInput, receiver interface{}) error

Query takes a query definition and writes the result to the receiver

func (*Gateway) StaticPlaygroundHandler added in v0.2.8

func (g *Gateway) StaticPlaygroundHandler(config PlaygroundConfig) http.Handler

StaticPlaygroundHandler returns a static UI http.HandlerFunc with custom configuration

type HTTPOperation added in v0.0.15

type HTTPOperation struct {
	Query         string                 `json:"query"`
	Variables     map[string]interface{} `json:"variables"`
	OperationName string                 `json:"operationName"`
	Extensions    struct {
		QueryPlanCache *PersistedQuerySpecification `json:"persistedQuery"`
	} `json:"extensions"`
}

HTTPOperation is the incoming payload when sending POST requests to the gateway

type Logger

type Logger interface {
	Debug(args ...interface{})
	Info(args ...interface{})
	Warn(args ...interface{})

	WithFields(fields LoggerFields) Logger
	QueryPlanStep(step *QueryPlanStep)
}

Logger logs messages

type LoggerFields

type LoggerFields map[string]interface{}

LoggerFields is a wrapper over a map of key,value pairs to associate with the log

type Merger

type Merger interface {
	Merge([]*ast.Schema) (*ast.Schema, error)
}

Merger is an interface for structs that are capable of taking a list of schemas and returning something that resembles a "merge" of those schemas.

type MergerFunc

type MergerFunc func([]*ast.Schema) (*ast.Schema, error)

MergerFunc is a wrapper of a function of the same signature as Merger.Merge

func (MergerFunc) Merge

func (m MergerFunc) Merge(sources []*ast.Schema) (*ast.Schema, error)

Merge invokes and returns the wrapped function

type Middleware

type Middleware interface {
	Middleware()
}

Middleware are things that can modify a gateway normal execution

type MiddlewareList

type MiddlewareList []Middleware

MiddlewareList is a list of Middlewares

type MinQueriesPlanner

type MinQueriesPlanner struct {
	Planner
	LocationPriorities []string
}

MinQueriesPlanner does the most basic level of query planning

func (*MinQueriesPlanner) Plan

Plan computes the nested selections that will need to be performed

func (*MinQueriesPlanner) WithLocationPriorities added in v0.1.1

func (p *MinQueriesPlanner) WithLocationPriorities(priorities []string) QueryPlanner

func (*MinQueriesPlanner) WithQueryerFactory added in v0.0.7

func (p *MinQueriesPlanner) WithQueryerFactory(factory *QueryerFactory) QueryPlanner

WithQueryerFactory returns a version of the planner with the factory set

type MockErrPlanner

type MockErrPlanner struct {
	Err error
}

MockErrPlanner always returns the provided error. Useful in testing.

func (*MockErrPlanner) Plan

type MockExecutor added in v0.0.15

type MockExecutor struct {
	Value map[string]interface{}
}

MockExecutor always returns a success with the provided value

func (*MockExecutor) Execute added in v0.0.15

func (e *MockExecutor) Execute(_ *ExecutionContext) (map[string]interface{}, error)

Execute returns the provided value

type MockPlanner

type MockPlanner struct {
	Plans QueryPlanList
}

MockPlanner always returns the provided list of plans. Useful in testing.

func (*MockPlanner) Plan

type NoQueryPlanCache added in v0.0.15

type NoQueryPlanCache struct{}

NoQueryPlanCache will always compute the plan for a query, regardless of the value passed as `hash`

func (*NoQueryPlanCache) Retrieve added in v0.0.15

func (p *NoQueryPlanCache) Retrieve(ctx *PlanningContext, _ *string, planner QueryPlanner) (QueryPlanList, error)

Retrieve just computes the query plan

type Option added in v0.0.7

type Option func(*Gateway)

Option is a function to be passed to New that configures the resulting schema

func WithAutomaticQueryPlanCache added in v0.0.15

func WithAutomaticQueryPlanCache() Option

WithAutomaticQueryPlanCache enables the "automatic persisted query" technique

func WithExecutor

func WithExecutor(e Executor) Option

WithExecutor returns an Option that sets the executor of the gateway

func WithLocationPriorities added in v0.1.1

func WithLocationPriorities(priorities []string) Option

func WithLogger added in v0.1.10

func WithLogger(l Logger) Option

WithLogger returns an Option that sets the logger of the gateway

func WithMerger

func WithMerger(m Merger) Option

WithMerger returns an Option that sets the merger of the gateway

func WithMiddlewares added in v0.0.5

func WithMiddlewares(middlewares ...Middleware) Option

WithMiddlewares returns an Option that adds middlewares to the gateway

func WithNoQueryPlanCache added in v0.0.15

func WithNoQueryPlanCache() Option

WithNoQueryPlanCache is the default option and disables any persisted query behavior

func WithPlanner

func WithPlanner(p QueryPlanner) Option

WithPlanner returns an Option that sets the planner of the gateway

func WithQueryFields added in v0.0.5

func WithQueryFields(fields ...*QueryField) Option

WithQueryFields returns an Option that adds the given query fields to the gateway

func WithQueryPlanCache added in v0.0.15

func WithQueryPlanCache(p QueryPlanCache) Option

WithQueryPlanCache sets the query plan cache that the gateway will use

func WithQueryerFactory added in v0.0.7

func WithQueryerFactory(factory *QueryerFactory) Option

WithQueryerFactory returns an Option that changes the queryer used by the planner when generating plans that interact with remote services.

type ParallelExecutor

type ParallelExecutor struct{}

ParallelExecutor executes the given query plan by starting at the root of the plan and walking down the path stitching the results together

func (*ParallelExecutor) Execute

func (executor *ParallelExecutor) Execute(ctx *ExecutionContext) (map[string]interface{}, error)

Execute returns the result of the query plan

type PersistedQuerySpecification added in v0.0.15

type PersistedQuerySpecification struct {
	Version int    `json:"version"`
	Hash    string `json:"sha256Hash"`
}

type Planner

type Planner struct {
	QueryerFactory *QueryerFactory
}

Planner is meant to be embedded in other QueryPlanners to share configuration

func (*Planner) GetQueryer

func (p *Planner) GetQueryer(ctx *PlanningContext, url string) graphql.Queryer

GetQueryer returns the queryer that should be used to resolve the plan

type PlannerWithLocationPriorities added in v0.1.1

type PlannerWithLocationPriorities interface {
	WithLocationPriorities(priorities []string) QueryPlanner
}

PlannerWithLocationFactory is an interface for planners with configurable location priorities

type PlannerWithQueryerFactory added in v0.0.7

type PlannerWithQueryerFactory interface {
	WithQueryerFactory(*QueryerFactory) QueryPlanner
}

PlannerWithQueryerFactory is an interface for planners with configurable queryer factories

type PlanningContext added in v0.0.5

type PlanningContext struct {
	Query     string
	Schema    *ast.Schema
	Locations FieldURLMap
	Gateway   *Gateway
}

PlanningContext is the input struct to the Plan method

type PlaygroundConfig added in v0.2.8

type PlaygroundConfig struct {
	Endpoint string             `json:"endpoint"`
	Settings PlaygroundSettings `json:"settings"`
}

PlaygroundConfig contains configuration for rendering a playground UI with a few, critical settings.

type PlaygroundSettings added in v0.2.8

type PlaygroundSettings struct {
	RequestCredentials   string            `json:"request.credentials"`
	RequestGlobalHeaders map[string]string `json:"request.globalHeaders"`
}

PlaygroundSettings contains settings for setting up a playground UI. It contains only a few, critical settings to provide a stronger backward-compatibility guarantee.

If you need more options, consider opening an issue or serving your own custom playground UI.

type QueryField added in v0.0.5

type QueryField struct {
	Name      string
	Type      *ast.Type
	Arguments ast.ArgumentDefinitionList
	Resolver  func(context.Context, map[string]interface{}) (string, error)
}

QueryField is a hook to add gateway-level fields to a gateway. Limited to only being able to resolve an id of an already existing type in order to keep business logic out of the gateway.

type QueryPlan

type QueryPlan struct {
	Operation           *ast.OperationDefinition
	RootStep            *QueryPlanStep
	FragmentDefinitions ast.FragmentDefinitionList
	FieldsToScrub       map[string][][]string
}

QueryPlan is the full plan to resolve a particular query

type QueryPlanCache added in v0.0.15

type QueryPlanCache interface {
	Retrieve(ctx *PlanningContext, hash *string, planner QueryPlanner) (QueryPlanList, error)
}

QueryPlanCache decides when to compute a plan

type QueryPlanList added in v0.1.0

type QueryPlanList []*QueryPlan

QueryPlanList is a list of plans which can be indexed by operation name

func (QueryPlanList) ForOperation added in v0.1.0

func (l QueryPlanList) ForOperation(name string) (*QueryPlan, error)

ForOperation returns the query plan meant to satisfy the given operation name

type QueryPlanStep

type QueryPlanStep struct {
	// execution meta data
	InsertionPoint []string
	Then           []*QueryPlanStep

	// required info to generate the query
	Queryer      graphql.Queryer
	ParentType   string
	ParentID     string
	SelectionSet ast.SelectionSet

	// pre-generated query stuff
	QueryDocument       *ast.QueryDocument
	QueryString         string
	FragmentDefinitions ast.FragmentDefinitionList
	Variables           Set
}

QueryPlanStep represents a step in the plan required to fulfill a query.

type QueryPlanner

type QueryPlanner interface {
	Plan(*PlanningContext) (QueryPlanList, error)
}

QueryPlanner is responsible for taking a string with a graphql query and returns the steps to fulfill it

type QueryerFactory added in v0.0.7

type QueryerFactory func(ctx *PlanningContext, url string) graphql.Queryer

QueryerFactory is a function that returns the queryer to use depending on the context

type RequestContext added in v0.0.15

type RequestContext struct {
	Context       context.Context
	Query         string
	OperationName string
	Variables     map[string]interface{}
	CacheKey      string
}

RequestContext holds all of the information required to satisfy the user's query

type RequestMiddleware

type RequestMiddleware graphql.NetworkMiddleware

RequestMiddleware is a middleware that can modify outbound requests to services

func (RequestMiddleware) Middleware

func (p RequestMiddleware) Middleware()

Middleware marks RequestMiddleware as a valid middleware

type ResponseMiddleware added in v0.0.3

type ResponseMiddleware func(ctx *ExecutionContext, response map[string]interface{}) error

ResponseMiddleware is a middleware that can modify the response before it is serialized and sent to the user

func (ResponseMiddleware) ExecutionMiddleware added in v0.0.3

func (p ResponseMiddleware) ExecutionMiddleware()

ExecutionMiddleware marks ResponseMiddleware as a valid execution middleware

func (ResponseMiddleware) Middleware added in v0.0.3

func (p ResponseMiddleware) Middleware()

Middleware marks ResponseMiddleware as a valid middleware

type Set

type Set map[string]bool

Set is a set

func (Set) Add

func (set Set) Add(k string)

Add adds the item to the set

func (Set) Has

func (set Set) Has(k string) bool

Has returns wether or not the string is in the set

func (Set) Remove

func (set Set) Remove(k string)

Remove removes the item from the set

Directories

Path Synopsis
cmd
gateway Module
examples module
auth Module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL