99designs / 99designs/gqlgen

How do I manipulate the context at root field level but after the root field resolver runs

Open
#2,650 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
10.8k
Forks
1.3k
Avg merge
2d 36m
Merged PRs (30d)
26

Description

### What happened?

I'm trying to inject a token into the golang context for each request, but only under certain condition based on the query. Because the token is only needed for loading certain GraphQL entities. On the other hand, I don't want to have this middleware to be applied using `AroundFields` either because if there are multiple such entities, i don't want to query the token multiple times which is expensive. i only want to query the token once.

So I wrote the following code and used `AroundRootFields`. But because this middleware runs before the `RootResolver` executes, `CollectFields` method will return me empty slice as nothing has been resolved.

```Go
srv.AroundRootFields(s.tokenMiddleware)

func (s *Server) tokenMiddleware(ctx context.Context, next graphql.RootResolver) graphql.Marshaler {
oc := graphql.GetOperationContext(ctx)
collected := graphql.CollectFieldsCtx(ctx, nil) // returns me empty slice
fields := getFieldsRecursively(
oc,
collected,
) // get back a slice of strings for the fields but this won't work

if !lo.Contains(fields, "specific_field_name") {
return next(oc)
}

token := s.getToken(ctx)
if token == nil {
return next(ctx)
}
return next(context.WithValue(ctx, "access_token", token))
}
```

### What did you expect?

Ideally I can have something like `PostRootResolverMiddleware` which executes **only once per root field** after root resolver runs but before passing context to the sub-field resolvers.

If this is not supported atm but shouldn't be too hard to implement, I can try putting out a PR too.

### Minimal graphql.schema and models to reproduce

### versions
- `go run github.com/99designs/gqlgen version`? `v0.17.26`
- `go version`? `1.20`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.