99designs / 99designs/gqlgen

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

未关闭
#2,650 2 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
Go
星标
10.8k
派生
1.3k
平均合并
2 天 36 分钟
30 天内合并 PR
26

描述

### 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`

贡献指南

打开贡献指南

调研方向

查看 gqlgen 的 middleware 系统,尤其是 AroundRootFields 以及 operation context 的构建方式。这个 issue 是关于添加 post-root-resolver middleware 的。首先检查 graphql/executor.go 和 graphql/context.go 中的执行流程,了解 root fields 在哪里被解析,以及 context 如何传递给 child resolvers。检查在 root resolution 之后是否已经存在 hook point。目标是在 root resolver 运行之后,根据已解析的 fields,每个 root field 修改一次 context。

由索引模型根据 Issue 内容生成。

评估

技术栈
go
领域
api, backend
Issue 类型
功能
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。