graphql-go / graphql-go/graphql
DefaultResolveFn can't be composed because it doesn't return an error
- Dominant language
- Go
- Stars
- 10.1k
- Forks
- 845
- PR merge metrics
- No merged PRs in 30d
Description
I have the following scenario and I'm trying to implement the Resolve function on `Thing`.
```go
type Base struct {
Simple string
}
type Thing struct {
Base
fancy string
}
func (t Thing) Resolve(p graphql.ResolveParams) (interface{}, error) {
// TODO: Delegate to fields in Base first
// If the fields are not found in the base, resolve them here
switch p.Info.FieldName {
case "Fancy":
return b.fancy + " is fancy", nil
default:
return nil, fmt.Errorf("no such field: %s", p.Info.FieldName)
}
}
```
As you can see, I don't want to re-implement the resolution of fields in Base just because Thing has a custom resolve function. Note that Base is embedded in Thing and I don't want to expose this implementation detail to the client by creating another layer of nesting in the graph.
I thought about calling DefaultResolveFn, but it doesn't return an error if the field is not found. I would really like a function I can call that will error if it can't figure out how to resolve a field. DefaultResolveFn can be a wrapper for that function and just drop the error. Then I could write:
```go
func (t Thing) Resolve(p graphql.ResolveParams) (interface{}, error) {
p2 := p
p2.Source = t.Base
resolved, err := graphql.DefaultResolveFnWithError(p2)
if err == nil {
return resolved, nil
}
// If the fields are not found in the base, resolve them here
switch p.Info.FieldName {
case "Fancy":
return b.fancy + " is fancy", nil
default:
return nil, fmt.Errorf("no such field: %s", p.Info.FieldName)
}
}
```
Of course, I could also write my own resolver function that errors, but then I run the risk of diverging from the upstream resolver.
If I make a PR that adds `DefaultResolveFnWithError` would it be accepted? Any opinions on what it should be named?
Contributor guide
Assessment
This issue has not been assessed yet.