graphql-go / graphql

An implementation of GraphQL for Go / Golang
MIT License
9.94k stars 841 forks source link

interface conversion: ast.Selection is *ast.FragmentSpread, not *ast.Field #627

Closed JoydS closed 2 years ago

JoydS commented 2 years ago

Hello Guys,

Im trying to use fragments :

fragment User on User {
  id
}
query getUsers {
  users(
    id: 1
  ) {
   ...User
  }
}

But I have the error : interface conversion: ast.Selection is *ast.FragmentSpread, not *ast.Field

I tried to follow this issue : https://github.com/graphql-go/graphql/issues/157#issuecomment-302868300

But I can't find a way to resolve this. Little help my be usefull,

Thanks!

JoydS commented 2 years ago

Hello guys,

Im sorry, the issue was from me, based on https://github.com/graphql-go/graphql/issues/157#issuecomment-302868300, I changed the code to have the full path of selected fields :

func GetSelectedFields(params graphql.ResolveParams) ([]string, error) {
    fieldASTs := params.Info.FieldASTs
    if len(fieldASTs) == 0 {
        err := fmt.Errorf("GetSelectedFields: ResolveParams has no fields")
        logrus.Error(err)
        return nil, err
    }
    return selectedFieldsFromSelections(params, fieldASTs[0].SelectionSet.Selections, "/")
}

func selectedFieldsFromSelections(params graphql.ResolveParams, selections []ast.Selection, suffix string) ([]string, error) {
    var selected []string
    for _, s := range selections {
        switch t := s.(type) {
        case *ast.Field:
            if s.GetSelectionSet() != nil {
                var subfields []ast.Selection
                for _, selection := range s.GetSelectionSet().Selections {
                    subfields = append(subfields, selection)
                }

                sel, err := selectedFieldsFromSelections(params, subfields, suffix+t.Name.Value+"/")
                if err != nil {
                    return nil, err
                }
                selected = append(selected, sel...)
            }
            selected = append(selected, suffix+s.(*ast.Field).Name.Value)
        case *ast.FragmentSpread:
            n := s.(*ast.FragmentSpread).Name.Value
            frag, ok := params.Info.Fragments[n]
            if !ok {
                err := fmt.Errorf("GetSelectedFields: ResolveParams has no fields")
                logrus.Error(err)
                return nil, err
            }
            sel, err := selectedFieldsFromSelections(params, frag.GetSelectionSet().Selections, suffix)
            if err != nil {
                return nil, err
            }
            selected = append(selected, sel...)
        default:
            err := fmt.Errorf("getSelectedFields: found unexpected selection type %v", t)
            logrus.Error(err)
            return nil, err
        }
    }
    return selected, nil
}