gbox

package module
v1.0.6 Latest Latest
Warning

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

Go to latest
Published: May 14, 2022 License: Apache-2.0 Imports: 49 Imported by: 0

README

Fast ⚡ reverse proxy in front of any GraphQL server for caching, securing and monitoring.

Unit Tests codecov Go Report Card Go Reference Artifact Hub

Features

  • 💾 Caching
    • RFC7234 compliant HTTP Cache.
    • Cache query operations results through types.
    • Auto invalidate cache through mutation operations.
    • Swr query results in background.
    • Cache query results to specific headers, cookies (varies).
  • 🔐 Securing
    • Disable introspection.
    • Limit operations depth, nodes and complexity.
  • 📈 Monitoring (Prometheus metrics)
    • Operations in flight.
    • Operations count.
    • Operations request durations.
    • Operations caching statuses.

How it works

Every single request sent by your clients will serve by GBox. The GBox reverse proxy will cache, validate, and collect metrics before pass through requests to your GraphQL server.

Diagram

Documentation

The GBox documentation can be browsed on Github page.

Inspiration

The GBox has been inspired by many others related work including:

Thanks to all the great people who created these projects!

Documentation

Index

Constants

View Source
const (
	CachingQueryResultStale cachingQueryResultStatus = "STALE"
	CachingQueryResultValid cachingQueryResultStatus = "VALID"
)

Variables

View Source
var ErrHandleUnknownOperationTypeError = errors.New("unknown operation type")
View Source
var ErrNotAllowIntrospectionQuery = errors.New("introspection query is not allowed")

Functions

func RegisterCachingStoreFactory

func RegisterCachingStoreFactory(schema string, factory CachingStoreFactory)

Types

type Caching

type Caching struct {
	// Storage DSN currently support redis and freecache only.
	// Redis example:
	// redis://username:password@localhost:6379?db=0&max_retries=3
	// more dsn options see at https://github.com/go-redis/redis/blob/v8.11.5/options.go#L31
	// Freecache example:
	// freecache://?cache_size=104857600
	// If not set it will be freecache://?cache_size=104857600 (cache size 100MB)
	StoreDsn string `json:"store_dsn,omitempty"`

	// Caching rules
	Rules CachingRules `json:"rules,omitempty"`

	// Caching varies
	Varies CachingVaries `json:"varies,omitempty"`

	// GraphQL type fields will be used to detect change of cached query results when user execute mutation query.
	// Example when execute mutation query bellow:
	// mutation { updateUser { id } }
	// if `updateUser` field have type User and id returning in example above is 1, all cache results of user id 1 will be purged.
	// If not set default value of it will be `id` for all types.
	TypeKeys graphql.RequestTypes `json:"type_keys,omitempty"`

	// Auto invalidate query result cached by mutation result type keys
	// Example: if you had cached query result of User type, when you make mutation query and result
	// of this query have type User with id's 3, all cached query result related with id 3 of User type will be purged.
	AutoInvalidate bool

	// Add debug headers like query result cache key,
	// plan cache key and query result had types keys or not...
	DebugHeaders bool
	// contains filtered or unexported fields
}

func (*Caching) Cleanup

func (c *Caching) Cleanup() error

func (*Caching) HandleRequest

func (c *Caching) HandleRequest(w http.ResponseWriter, r *cachingRequest, h caddyhttp.HandlerFunc) error

HandleRequest caching GraphQL query result by configured rules and varies.

func (*Caching) Provision

func (c *Caching) Provision(ctx caddy.Context) error

func (*Caching) PurgeQueryResultByOperationName

func (c *Caching) PurgeQueryResultByOperationName(ctx context.Context, name string) error

func (*Caching) PurgeQueryResultBySchema

func (c *Caching) PurgeQueryResultBySchema(ctx context.Context, schema *graphql.Schema) error

func (*Caching) PurgeQueryResultByTypeField

func (c *Caching) PurgeQueryResultByTypeField(ctx context.Context, typeName, fieldName string) error

func (*Caching) PurgeQueryResultByTypeKey

func (c *Caching) PurgeQueryResultByTypeKey(ctx context.Context, typeName, fieldName string, value interface{}) error

func (*Caching) PurgeQueryResultByTypeName

func (c *Caching) PurgeQueryResultByTypeName(ctx context.Context, name string) error

func (*Caching) Validate

func (c *Caching) Validate() error

type CachingRule

type CachingRule struct {
	// GraphQL type to cache
	// ex: `User` will cache all query results have type User
	// ex: `User { is_admin }` will cache all query results have type User and have field `is_admin`.
	// If not set this rule will match all types.
	Types graphql.RequestTypes `json:"types,omitempty"`

	// how long query results that match the rule types should be store.
	MaxAge caddy.Duration `json:"max_age,omitempty"`

	// how long stale query results that match the rule types should be served while fresh data is already being fetched in the background.
	Swr caddy.Duration `json:"swr,omitempty"`

	// Varies name apply to query results that match the rule types.
	// If not set query results will cache public.
	Varies []string `json:"varies,omitempty"`
}

type CachingRules

type CachingRules map[string]*CachingRule

type CachingStatus

type CachingStatus string
const (
	CachingStatusPass CachingStatus = "PASS"
	CachingStatusHit  CachingStatus = "HIT"
	CachingStatusMiss CachingStatus = "MISS"
)

type CachingStore

type CachingStore struct {
	*marshaler.Marshaler
	// contains filtered or unexported fields
}

func FreeCacheStoreFactory

func FreeCacheStoreFactory(u *url.URL) (*CachingStore, error)

func NewCachingStore

func NewCachingStore(u *url.URL) (*CachingStore, error)

func RedisCachingStoreFactory

func RedisCachingStoreFactory(u *url.URL) (*CachingStore, error)

type CachingStoreFactory

type CachingStoreFactory = func(u *url.URL) (*CachingStore, error)

type CachingVaries

type CachingVaries map[string]*CachingVary

type CachingVary

type CachingVary struct {
	// Headers names for identifier query result cache key.
	Headers []string `json:"headers,omitempty"`

	// Cookies names for identifier query result cache key.
	Cookies []string `json:"cookies,omitempty"`
}

CachingVary using to compute query result cache key by http request cookies and headers.

type Complexity

type Complexity struct {
	// Max query depth accept, disabled by default.
	MaxDepth int `json:"max_depth,omitempty"`

	// Query node count limit, disabled by default.
	NodeCountLimit int `json:"node_count_limit,omitempty"`

	// Max query complexity, disabled by default.
	MaxComplexity int `json:"complexity,omitempty"`
}

type Handler

type Handler struct {
	// Rewrite
	RewriteRaw json.RawMessage `json:"rewrite_raw,omitempty" caddy:"namespace=http.handlers inline_key=rewrite"`

	// Reverse proxy
	ReverseProxyRaw json.RawMessage `json:"reverse_proxy,omitempty" caddy:"namespace=http.handlers inline_key=reverse_proxy"`

	// Upstream graphql server url
	Upstream string `json:"upstream,omitempty"`

	// Fetch schema interval, disabled by default.
	FetchSchemaInterval caddy.Duration `json:"fetch_schema_interval,omitempty"`

	// Fetch schema request timeout, "30s" by default
	FetchSchemaTimeout caddy.Duration `json:"fetch_schema_timeout,omitempty"`

	// Fetch schema headers
	FetchSchemaHeader http.Header `json:"fetch_schema_headers,omitempty"`

	// Whether to disable introspection request of downstream.
	DisabledIntrospection bool `json:"disabled_introspection,omitempty"`

	// Whether to disable playground paths.
	DisabledPlaygrounds bool `json:"disabled_playgrounds,omitempty"`

	// Request complexity settings, disabled by default.
	Complexity *Complexity `json:"complexity,omitempty"`

	// Caching queries result settings, disabled by default.
	Caching *Caching `json:"caching,omitempty"`

	// Cors origins
	CORSOrigins []string `json:"cors_origins,omitempty"`

	// Cors allowed headers
	CORSAllowedHeaders []string `json:"cors_allowed_headers,omitempty"`

	ReverseProxy *reverseproxy.Handler `json:"-"`
	Rewrite      *rewrite.Rewrite      `json:"-"`
	// contains filtered or unexported fields
}

Handler implements an HTTP handler as a GraphQL reverse proxy server for caching, securing, and monitoring.

func (*Handler) AdminGraphQLHandle

func (h *Handler) AdminGraphQLHandle(w http.ResponseWriter, r *http.Request)

AdminGraphQLHandle purging query result cached and describe cache key.

func (Handler) CaddyModule

func (h Handler) CaddyModule() caddy.ModuleInfo

func (*Handler) Cleanup

func (h *Handler) Cleanup() error

func (*Handler) GraphQLHandle

func (h *Handler) GraphQLHandle(w http.ResponseWriter, r *http.Request)

GraphQLHandle ensure GraphQL request is safe before forwarding to upstream and caching query result of it.

func (*Handler) GraphQLOverWebsocketHandle

func (h *Handler) GraphQLOverWebsocketHandle(w http.ResponseWriter, r *http.Request)

GraphQLOverWebsocketHandle handling websocket connection between client & upstream.

func (*Handler) Provision

func (h *Handler) Provision(ctx caddy.Context) (err error)

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, n caddyhttp.Handler) error

func (*Handler) UnmarshalCaddyfile

func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) (err error)

nolint:funlen,gocyclo

func (*Handler) Validate

func (h *Handler) Validate() error

type Metrics

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

Directories

Path Synopsis
Copied from https://github.com/caddyserver/xcaddy/blob/b7fd102f41e12be4735dc77b0391823989812ce8/environment.go#L251
Copied from https://github.com/caddyserver/xcaddy/blob/b7fd102f41e12be4735dc77b0391823989812ce8/environment.go#L251
internal

Jump to

Keyboard shortcuts

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