Documentation ¶
Overview ¶
Package core provides an API to include and use the GraphJin compiler with your own code. For detailed documentation visit https://graphjin.com
Example usage:
package main import ( "database/sql" "fmt" "time" "github.com/dosco/graphjin/core" _ "github.com/jackc/pgx/v4/stdlib" ) func main() { db, err := sql.Open("pgx", "postgres://postgrs:@localhost:5432/example_db") if err != nil { log.Fatal(err) } gj, err := core.NewGraphJin(nil, db) if err != nil { log.Fatal(err) } query := ` query { posts { id title } }` ctx = context.WithValue(ctx, core.UserIDKey, 1) res, err := gj.GraphQL(ctx, query, nil) if err != nil { log.Fatal(err) } }
Index ¶
- Constants
- func GetConfigName() string
- type Column
- type Config
- type Delete
- type Error
- type GraphJin
- func (g *GraphJin) GraphQL(c context.Context, query string, vars json.RawMessage, rc *ReqConfig) (*Result, error)
- func (g *GraphJin) GraphQLByName(c context.Context, operation OpType, name string, vars json.RawMessage, ...) (*Result, error)
- func (g *GraphJin) IsProd() bool
- func (g *GraphJin) Reload() error
- func (g *GraphJin) Subscribe(c context.Context, query string, vars json.RawMessage, rc *ReqConfig) (*Member, error)
- type Header
- type Insert
- type Member
- type Namespace
- type OpType
- type Option
- type Query
- type ReqConfig
- type Resolver
- type ResolverConfig
- type ResolverProps
- type ResolverReq
- type Result
- type Role
- type RoleTable
- type Table
- type Update
- type Upsert
Constants ¶
const ( // Name of the authentication provider. Eg. google, github, etc UserIDProviderKey contextkey = iota // The raw user id (jwt sub) value UserIDRawKey // User ID value for authenticated users UserIDKey // User role if pre-defined UserRoleKey )
Constants to set values on the context passed to the NewGraphJin function
Variables ¶
This section is empty.
Functions ¶
func GetConfigName ¶ added in v0.17.7
func GetConfigName() string
Types ¶
type Column ¶
type Column struct { ID int32 Name string Type string Primary bool Array bool ForeignKey string `mapstructure:"related_to"` }
Column struct defines a database column
type Config ¶
type Config struct { // SecretKey is used to encrypt opaque values such as // the cursor. Auto-generated if not set SecretKey string `mapstructure:"secret_key"` // DisableAllowList when set to true entirely disables the // allow list workflow and all queries are always compiled // even in production (Warning possible security concern) DisableAllowList bool `mapstructure:"disable_allow_list"` // ConfigPath is the default path to find all configuration // files and scripts under ConfigPath string `mapstructure:"config_path"` // ScriptPath if the path to the script files if not set the // path is assumed to be the same as the config path ScriptPath string `mapstructure:"script_path"` // SetUserID forces the database session variable `user.id` to // be set to the user id SetUserID bool `mapstructure:"set_user_id"` // DefaultBlock ensures that in anonymous mode (role 'anon') all tables // are blocked from queries and mutations. To open access to tables in // anonymous mode they have to be added to the 'anon' role config DefaultBlock bool `mapstructure:"default_block"` // Vars is a map of hardcoded variables that can be leveraged in your // queries. (eg. variable admin_id will be $admin_id in the query) Vars map[string]string `mapstructure:"variables"` // HeaderVars is a map of dynamic variables that map to http header values HeaderVars map[string]string `mapstructure:"header_variables"` // Blocklist is a list of tables and columns that should be filtered // out from any and all queries Blocklist []string // Resolvers contain the configs for custom resolvers. For example the `remote_api` // resolver would join json from a remote API into your query response Resolvers []ResolverConfig // Tables contains all table specific configuration such as aliased tables // creating relationships between tables, etc Tables []Table // RolesQuery if set enabled attribute based access control. This query // is used to fetch the user attribute that then dynamically define the users // role RolesQuery string `mapstructure:"roles_query"` // Roles contains all the configuration for all the roles you want to support // `user` and `anon` are two default roles. User role is for when a user ID is // available and Anon when it's not // // If you're using the RolesQuery config to enable atribute based acess control then // you can add more custom roles Roles []Role // Inflections is to add additionally singular to plural mappings // to the engine (eg. sheep: sheep) Inflections []string `mapstructure:"inflections"` // Disable inflections. Inflections are deprecated and will be // removed in next major version EnableInflection bool `mapstructure:"enable_inflection"` // Customize singular suffix // By default is set to "ByID" SingularSuffix string `mapstructure:"singular_suffix"` // Database type name Defaults to 'postgres' (options: mysql, postgres) DBType string `mapstructure:"db_type"` // Log warnings and other debug information Debug bool // SubsPollDuration is the database polling duration (in seconds) // used by subscriptions to query for updates. // Default set to 5 seconds SubsPollDuration time.Duration `mapstructure:"subs_poll_duration"` // DefaultLimit sets the default max limit (number of rows) when a // limit is not defined in the query or the table role config // Default set to 20 DefaultLimit int `mapstructure:"default_limit"` // DisableAgg disables all aggregation functions like count, sum, etc DisableAgg bool `mapstructure:"disable_agg_functions"` // DisableFuncs disables all functions like count, length, etc DisableFuncs bool `mapstructure:"disable_functions"` // EnableCamelcase enables autp camel case terms in GraphQL to snake case in SQL EnableCamelcase bool `mapstructure:"enable_camelcase"` // Enable production mode. This defaults to true if GO_ENV is set to // "production". When true the allow list is enforced Production bool // DBSchemaPollDuration sets the duration for polling the database // schema to detect changes to it. GraphJin is reinitialized when a // change is detected DBSchemaPollDuration time.Duration `mapstructure:"db_schema_poll_duration"` // contains filtered or unexported fields }
Core struct contains core specific config value
func ReadInConfig ¶
ReadInConfig reads in the config file for the environment specified in the GO_ENV environment variable. This is the best way to create a new GraphJin config.
func ReadInConfigFS ¶ added in v0.17.0
ReadInConfigFS is the same as ReadInConfig but it also takes a filesytem as an argument
func (*Config) AddRoleTable ¶
AddRoleTable function is a helper function to make it easy to add per-table row-level config
func (*Config) RemoveRoleTable ¶ added in v0.16.7
func (*Config) SetResolver ¶ added in v0.15.56
type GraphJin ¶
func NewGraphJin ¶
NewGraphJin creates the GraphJin struct, this involves querying the database to learn its schemas and relationships
func (*GraphJin) GraphQL ¶
func (g *GraphJin) GraphQL( c context.Context, query string, vars json.RawMessage, rc *ReqConfig) (*Result, error)
GraphQL function is called on the GraphJin struct to convert the provided GraphQL query into an SQL query and execute it on the database. In production mode prepared statements are directly used and no query compiling takes places.
In developer mode all names queries are saved into a file `allow.list` and in production mode only queries from this file can be run.
func (*GraphJin) GraphQLByName ¶ added in v0.20.4
func (*GraphJin) IsProd ¶ added in v0.16.28
IsProd return true for production mode or false for development mode
type Member ¶
type Member struct { Result chan *Result // contains filtered or unexported fields }
func (*Member) Unsubscribe ¶
func (m *Member) Unsubscribe()
type Option ¶ added in v0.17.0
type Option func(*graphjin) error
func OptionSetFS ¶ added in v0.17.0
func OptionSetNamespace ¶ added in v0.17.21
type Query ¶
type Query struct { Limit int Filters []string Columns []string DisableFunctions bool `mapstructure:"disable_functions"` Block bool }
Query struct contains access control values for query operations
type ReqConfig ¶
type ReqConfig struct { // Namespace is used to namespace requests within a single instance of GraphJin. For example queries with the same name // can exist in allow list in seperate namespaces. Namespace Namespace // APQKey is set when using GraphJin with automatic persisted queries APQKey string // Pass additional variables complex variables such as functions that return string values. Vars map[string]interface{} }
ReqConfig is used to pass request specific config values to the GraphQLEx and SubscribeEx functions. Dynamic variables can be set here.
type Resolver ¶ added in v0.15.56
type Resolver interface {
Resolve(context.Context, ResolverReq) ([]byte, error)
}
Resolver interface is used to create custom resolvers Custom resolvers must return a JSON value to be merged into the response JSON.
Example Redis Resolver:
type Redis struct { Addr string client redis.Client } func newRedis(v map[string]interface{}) (*Redis, error) { re := &Redis{} if err := mapstructure.Decode(v, re); err != nil { return nil, err } re.client := redis.NewClient(&redis.Options{ Addr: re.Addr, Password: "", // no password set DB: 0, // use default DB }) return re, nil } func (r *remoteAPI) Resolve(req ResolverReq) ([]byte, error) { val, err := rdb.Get(ctx, req.ID).Result() if err != nil { return err } return val, nil } func main() { conf := core.Config{ Resolvers: []Resolver{ Name: "cached_profile", Type: "redis", Table: "users", Column: "id", Props: []ResolverProps{ "addr": "localhost:6379", }, }, } gj.conf.SetResolver("redis", func(v ResolverProps) (Resolver, error) { return newRedis(v) }) gj, err := core.NewGraphJin(conf, db) if err != nil { log.Fatal(err) } }
type ResolverConfig ¶ added in v0.15.56
type ResolverConfig struct { Name string Type string Schema string Table string Column string StripPath string `mapstructure:"strip_path"` Props ResolverProps `mapstructure:",remain"` }
ResolverConfig struct defines a custom resolver
type ResolverProps ¶ added in v0.15.56
type ResolverProps map[string]interface{}
ResolverProps is a map of properties from the resolver config to be passed to the customer resolver's builder (new) function
type ResolverReq ¶ added in v0.15.56
type Result ¶
type Result struct { Errors []Error `json:"errors,omitempty"` Vars json.RawMessage `json:"-"` Data json.RawMessage `json:"data,omitempty"` // contains filtered or unexported fields }
Result struct contains the output of the GraphQL function this includes resulting json from the database query and any error information
func (*Result) CacheControl ¶ added in v0.16.44
func (*Result) OperationName ¶
type Role ¶
type Role struct { Name string Match string Tables []RoleTable // contains filtered or unexported fields }
Role struct contains role specific access control values for for all database tables
type RoleTable ¶
type RoleTable struct { Name string Schema string ReadOnly bool `mapstructure:"read_only"` Query *Query Insert *Insert Update *Update Upsert *Upsert Delete *Delete }
RoleTable struct contains role specific access control values for a database table
type Table ¶
type Table struct { Name string Schema string Table string Type string Blocklist []string Columns []Column OrderBy map[string][]string `mapstructure:"order_by"` }
Table struct defines a database table