restql

package
v6.7.2 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2023 License: MIT Imports: 12 Imported by: 2

Documentation

Overview

Package restql provides tools to integrate plugins in the restQL platform.

The primary features of this package are: • Provide a registration point for plugins. • Define interfaces for all the plugin types, allowing type safe integration. • Provide access to contextualized logger.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrMappingsNotFoundInDatabase     = errors.New("mappings not found in database")
	ErrQueryNotFoundInDatabase        = errors.New("query not found in database")
	ErrDatabaseCommunicationFailed    = errors.New("failed to communicate with the database")
	ErrMappingAlreadyExistsInDatabase = errors.New("mapping already exist in database, create operation not allowed")
)

Errors returned by Database plugin

View Source
var ErrMappingsNotFound = errors.New("mappings not found")

ErrMappingsNotFound is the error returned when the resource mappings is not found anywhere

View Source
var ErrNamespaceNotFound = errors.New("namespace not found")

ErrNamespaceNotFound is the error returned when the namespace is not found anywhere

View Source
var ErrQueryNotFound = errors.New("query not found")

ErrQueryNotFound is the error returned when the query text is not found anywhere

Functions

func RegisterPlugin

func RegisterPlugin(pluginInfo PluginInfo)

RegisterPlugin indexes the provided plugin information for latter usage by restQL in runtime. It supports registration of multiple Lifecycle plugins but only one Database plugin. In case of failure to register the plugin a warn message will be printed to the os.Stdout.

func WithLogger

func WithLogger(ctx context.Context, l Logger) context.Context

WithLogger stores a logger instance in a child context.Context created from the given context.Context. If a logger instance is already present, then it returns the current context.

Types

type Body

type Body interface{}

Body represents a HTTP body in a request or response.

type DatabasePlugin

type DatabasePlugin interface {
	Plugin

	FindAllNamespaces(ctx context.Context) ([]string, error)
	FindQueriesForNamespace(ctx context.Context, namespace string, archived bool) ([]SavedQuery, error)
	FindQueryWithAllRevisions(ctx context.Context, namespace string, queryName string, archived bool) (SavedQuery, error)
	FindQuery(ctx context.Context, namespace string, name string, revision int) (SavedQueryRevision, error)
	CreateQueryRevision(ctx context.Context, namespace string, queryName string, content string) error
	UpdateQueryArchiving(ctx context.Context, namespace string, queryName string, archived bool) error
	UpdateRevisionArchiving(ctx context.Context, namespace string, name string, revision int, archived bool) error

	FindAllTenants(ctx context.Context) ([]string, error)
	FindMappingsForTenant(ctx context.Context, tenantID string) ([]Mapping, error)
	CreateMapping(ctx context.Context, tenantID string, mappingsName string, url string) error
	SetMapping(ctx context.Context, tenantID string, mappingsName string, url string) error
}

DatabasePlugin is the interface that defines the obligatory operations needed from a database.

type DoneResource

type DoneResource struct {
	Status          int
	Success         bool
	IgnoreErrors    bool
	CacheControl    ResourceCacheControl
	Method          string
	URL             string
	RequestParams   map[string]interface{}
	RequestHeaders  map[string]string
	RequestBody     interface{}
	ResponseHeaders map[string]string
	ResponseBody    *ResponseBody
	ResponseTime    int64
}

DoneResource represents a statement result.

type DoneResources

type DoneResources []interface{}

DoneResources represents a multiplexed statement result.

type HTTPRequest

type HTTPRequest struct {
	Method  string
	Schema  string
	Host    string
	Path    string
	Query   map[string]interface{}
	Body    Body
	Headers Headers
	Timeout time.Duration
}

HttpRequest represents a HTTP call to be made to an upstream dependency defined by the mappings.

type HTTPResponse

type HTTPResponse struct {
	URL        string
	StatusCode int
	Body       *ResponseBody
	Headers    Headers
	Duration   time.Duration
}

HttpResponse represents a HTTP call result from an upstream dependency defined by the mappings.

type Headers

type Headers map[string]string

Headers represents all HTTP header in a request or response.

type LifecyclePlugin

type LifecyclePlugin interface {
	Plugin
	BeforeTransaction(ctx context.Context, tr TransactionRequest) context.Context
	AfterTransaction(ctx context.Context, tr TransactionResponse) context.Context
	BeforeQuery(ctx context.Context, query string, queryCtx QueryContext) context.Context
	AfterQuery(ctx context.Context, query string, result map[string]interface{}) context.Context
	BeforeRequest(ctx context.Context, request HTTPRequest) context.Context
	AfterRequest(ctx context.Context, request HTTPRequest, response HTTPResponse, err error) context.Context
}

LifecyclePlugin is the interface that defines all possible hooks during the query execution.

type Logger

type Logger interface {
	Panic(msg string, fields ...interface{})
	Fatal(msg string, fields ...interface{})
	Error(msg string, err error, fields ...interface{})
	Warn(msg string, fields ...interface{})
	Info(msg string, fields ...interface{})
	Debug(msg string, fields ...interface{})
	With(key string, value interface{}) Logger
}

Logger is the interface that wraps all methods for log handling

func GetLogger

func GetLogger(ctx context.Context) Logger

GetLogger extracts a logger instance from the given context.Context. If none is present, then a no operation logger is returned.

type Mapping

type Mapping struct {
	Source Source
	// contains filtered or unexported fields
}

Mapping represents the association of a name to a REST resource url. It support special syntax in the URL to provide dynamic value substitution, like: • Path parameters: can be defined by placing a colon (:) before an identifier in the URL path, for example "http://some.api/:id", will replace ":id" by the value of the "id" parameter in the query definition. • QueryRevisions parameters: can be defined by placing a colon (:) before an identifier in the URL query, for example "http://some.api?:page", will replace ":page" by the value of the "page" parameter in the query definition creating the URL "http://some.api?page=<value>".

func NewMapping

func NewMapping(resource, url string) (Mapping, error)

NewMapping constructs a Mapping value from a resource name and a canonical URL with optional identifiers for path and query parameters.

func (Mapping) Host

func (m Mapping) Host() string

Host returns the resource URL host

func (Mapping) IsPathParam

func (m Mapping) IsPathParam(name string) bool

IsPathParam returns true if the given name is a path parameter identifier

func (Mapping) IsQueryParam

func (m Mapping) IsQueryParam(name string) bool

IsQueryParam returns true if the given name is a query parameter identifier

func (Mapping) PathWithParams

func (m Mapping) PathWithParams(params map[string]interface{}) string

PathWithParams takes a map of key/value pairs and use it to build a path string with the all identifiable parameters resolved. For example, if the mapping URL is defined as "http://some.api/:id/", then this method will lookup for a "id" key in the given map and use its value to build the result "http://some.api/<value>/".

func (Mapping) QueryWithParams

func (m Mapping) QueryWithParams(params map[string]interface{}) map[string]interface{}

QueryWithParams takes a map of key/value pairs and use it to build a query parameters map with the all identifiable parameters resolved. For example, if the mapping URL is defined as "http://some.api?:page", then this method will lookup for a "page" key in the given map and use its value to build the result map[string]interface{}{"page": <value>}.

func (Mapping) ResourceName

func (m Mapping) ResourceName() string

ResourceName return the name associated with the resource URL

func (Mapping) Schema

func (m Mapping) Schema() string

Schema returns the resource URL schema

func (Mapping) URL

func (m Mapping) URL() string

URL returns the original resource location provided

type Plugin

type Plugin interface {
	Name() string
}

Plugin is the root interface that allows general handling of the plugins instance when need.

type PluginInfo

type PluginInfo struct {
	Name string
	Type PluginType
	New  func(Logger) (Plugin, error)
}

PluginInfo represents a plugin instance associating a name and type to a constructor function.

func GetDatabasePlugin

func GetDatabasePlugin() (PluginInfo, bool)

func GetLifecyclePlugins

func GetLifecyclePlugins() []PluginInfo

type PluginType

type PluginType int

PluginType is an enum of possible plugin types supported by restQL, currently supports LifecyclePluginType and DatabasePluginType.

const (
	LifecyclePluginType PluginType = iota
	DatabasePluginType
)

Plugin types

func (PluginType) String

func (pt PluginType) String() string

type QueryContext

type QueryContext struct {
	Mappings map[string]Mapping
	Options  QueryOptions
	Input    QueryInput
}

QueryContext represents all data related to a query execution like query identification, input values and resource mappings.

type QueryInput

type QueryInput struct {
	Params  map[string]interface{}
	Body    interface{}
	Headers map[string]string
}

QueryInput represents all the data provided by the client when requesting the execution of the query.

type QueryOptions

type QueryOptions struct {
	Namespace string
	Id        string
	Revision  int
	Tenant    string
}

QueryOptions represents the identity of the query being executed

type ResourceCacheControl

type ResourceCacheControl struct {
	NoCache bool
	MaxAge  ResourceCacheControlValue
	SMaxAge ResourceCacheControlValue
}

ResourceCacheControl represent cache control directives returned by upstream during statement resolution.

type ResourceCacheControlValue

type ResourceCacheControlValue struct {
	Exist bool
	Time  int
}

ResourceCacheControlValue represents the values a cache control directive is able to have. It can either be present and have a integer time value or not be present in the upstream response.

type ResponseBody

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

ResponseBody is a wrapper that allows restQL to defer JSON parsing the HTTP body of an upstream response.

Internally it stores two values: a byte slice and a interface. The most common scenario will be of creating a ResponseBody from the byte slice red from the HTTP response and returning it to downstream.

When features need to access the content of the JSON response, they can use the Unmarshal method to get it.

If the byte slice is unmarshalled or a new value is set on the response body with SetValue method, then the Marshal and Unmarshal function will operate using this value rather then the byte slice.

func NewResponseBodyFromBytes

func NewResponseBodyFromBytes(log Logger, b []byte) *ResponseBody

NewResponseBodyFromBytes creates a ResponseBody wrapper from an HTTP response data.

func NewResponseBodyFromValue

func NewResponseBodyFromValue(log Logger, v interface{}) *ResponseBody

NewResponseBodyFromValue creates a ResponseBody wrapper from a generic value, usually from an error.

func (*ResponseBody) Bytes

func (r *ResponseBody) Bytes() []byte

Bytes return the bytes data wrapped.

func (*ResponseBody) Clear

func (r *ResponseBody) Clear()

Clear removes all internal content.

func (*ResponseBody) Marshal

func (r *ResponseBody) Marshal() (interface{}, error)

Marshal returns the content of ResponseBody ready to be sent to downstream.

This method can process the content in 4 ways:

  • If there is a generic data, marshal it using a JSON parser and return the result as a json.RawMessage.
  • Else, if the byte slice is empty, return nil.
  • Else, if the byte slice is not an valid JSON, stringify it.
  • Finally, if the byte slice is not empty and is a valid json, return it as a json.RawMessage.

func (*ResponseBody) SetValue

func (r *ResponseBody) SetValue(v interface{})

SetValue defines a generic value to replace the byte slice data.

func (*ResponseBody) Unmarshal

func (r *ResponseBody) Unmarshal() interface{}

Unmarshal returns the content of ResponseBody ready to be manipulated internally by restQL.

This method can process the content in 4 ways:

  • If there is a generic data, return it.
  • Else, if the byte slice is empty or is not a valid json, return it as a string.
  • Finally, if it is valid to be manipulated, then unmarshal it and return.

func (*ResponseBody) Valid

func (r *ResponseBody) Valid() bool

Valid return true if the ResponseBody content can be manipulated by restQL.

func (*ResponseBody) Value

func (r *ResponseBody) Value() interface{}

Value return the generic data wrapped.

type SavedQuery

type SavedQuery struct {
	Namespace string
	Name      string
	Archived  bool
	Revisions []SavedQueryRevision
}

SavedQuery represents a query stored in database.

type SavedQueryRevision

type SavedQueryRevision struct {
	Name     string
	Text     string
	Revision int
	Archived bool
	Source   Source
}

SavedQueryRevision represents a query revision stored in database.

type Source

type Source string
var (
	DatabaseSource   Source = "database"
	ConfigFileSource Source = "config"
	EnvSource        Source = "env"
)

type TransactionRequest

type TransactionRequest struct {
	Url    *url.URL
	Method string
	Header http.Header
}

TransactionRequest represents a query execution transaction received through the /run-query/* endpoints.

type TransactionResponse

type TransactionResponse struct {
	Status int
	Header http.Header
	Body   []byte
}

TransactionResponse represents a query execution result from a transaction received through the /run-query/* endpoints.

Jump to

Keyboard shortcuts

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