Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
Err error
}

// StepHook is a function that can be executed before or after a step
type StepHook func(ctx *ExecutionContext) error

// execution is broken up into two phases:
// - the first walks down the dependency graph execute the network request
// - the second strips the id fields from the response and provides a
Expand All @@ -48,6 +51,8 @@
Variables map[string]interface{}
RequestContext context.Context
RequestMiddlewares []graphql.NetworkMiddleware
PreExecutionHook StepHook
PostExecutionHook StepHook
}

// Execute returns the result of the query plan
Expand Down Expand Up @@ -202,6 +207,21 @@
// log the query
ctx.logger.QueryPlanStep(step)

// Execute pre-execution hook if present
if ctx.PreExecutionHook != nil {
func() {
defer func() {
if r := recover(); r != nil {
ctx.logger.Warn("Pre-execution hook panicked: ", r)
}
}()
if hookErr := ctx.PreExecutionHook(ctx); hookErr != nil {
ctx.logger.Warn("Pre-execution hook failed: ", hookErr)
// Continue execution even if pre-hook fails, but log the error
}
}()
}

// the list of variables and their definitions that pertain to this query
variables := map[string]interface{}{}

Expand Down Expand Up @@ -286,6 +306,21 @@
queryResult = resultObj
}

// Execute post-execution hook if present
if ctx.PostExecutionHook != nil {
func() {
defer func() {
if r := recover(); r != nil {
ctx.logger.Warn("Post-execution hook panicked: ", r)
}
}()
if hookErr := ctx.PostExecutionHook(ctx); hookErr != nil {
ctx.logger.Warn("Post-execution hook failed: ", hookErr)
// Continue execution even if post-hook fails, but log the error
}
}()
}

Check failure on line 323 in execute.go

View workflow job for this annotation

GitHub Actions / Lint

File is not properly formatted (gofmt)
// if there are next steps
var dependentSteps []dependentStepArgs
if len(step.Then) > 0 {
Expand Down
19 changes: 18 additions & 1 deletion gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ type Gateway struct {
queryerFactory *QueryerFactory
queryPlanCache QueryPlanCache
locationPriorities []string

preExecutionHook StepHook
postExecutionHook StepHook
// group up the list of middlewares at startup to avoid it during execution
requestMiddlewares []graphql.NetworkMiddleware
responseMiddlewares []ResponseMiddleware
Expand Down Expand Up @@ -86,6 +87,8 @@ func (g *Gateway) Execute(ctx *RequestContext, plans QueryPlanList) (map[string]
RequestMiddlewares: g.requestMiddlewares,
Plan: plan,
Variables: ctx.Variables,
PreExecutionHook: g.preExecutionHook,
PostExecutionHook: g.postExecutionHook,
}

// TODO: handle plans of more than one query
Expand Down Expand Up @@ -292,6 +295,20 @@ func WithLocationPriorities(priorities []string) Option {
}
}

// WithPreExecutionHook returns an Option that sets a pre-execution hook for all steps
func WithPreExecutionHook(hook StepHook) Option {
return func(g *Gateway) {
g.preExecutionHook = hook
}
}

// WithPostExecutionHook returns an Option that sets a post-execution hook for all steps
func WithPostExecutionHook(hook StepHook) Option {
return func(g *Gateway) {
g.postExecutionHook = hook
}
}

// WithLogger returns an Option that sets the logger of the gateway
func WithLogger(l Logger) Option {
return func(g *Gateway) {
Expand Down
Loading