Graphql-go: Support extend type syntax

Created on 22 Jan 2018  路  8Comments  路  Source: graph-gophers/graphql-go

I want to build several schema for different tenant, I want to some type is extendable, for user, if some module is enabled, the new query function will added to user type.

From this article Extend your Graphcool API with Resolvers, found the syntax like

extend type Query {
  getWeatherByCity(city: String!): GetWeatherByCityPayload
}

Is it possible to implement this syntax in graphql-go ? Just merge the field to the main type, or is there any way to do this in graphql-go except dynamic generate schema ?

Most helpful comment

Seems, it's not too hard to do this, the worst implementation is

        case "extend":
            switch t:=l.ConsumeIdent();t {
            case "type":
                obj := parseObjectDecl(l)
                obj.Desc = desc
                old := s.Types[obj.Name]
                if old == nil {
                    l.SyntaxError(fmt.Sprintf(`extend type %q not found`, obj.Name))
                }
                origin, ok := old.(*Object)
                if !ok {
                    l.SyntaxError(fmt.Sprintf(`extend type %q must be object, but found %q`, obj.Name, old.Kind()))
                }
                origin.Fields = append(origin.Fields, obj.Fields...)
            default:
                l.SyntaxError(fmt.Sprintf(`unexpected %q, expecting "type"`, t))
            }

add this to schema.go, and it works, maybe the extend type should be tracked in Object, can do the same for interface or input, very interesting.

All 8 comments

Seems, it's not too hard to do this, the worst implementation is

        case "extend":
            switch t:=l.ConsumeIdent();t {
            case "type":
                obj := parseObjectDecl(l)
                obj.Desc = desc
                old := s.Types[obj.Name]
                if old == nil {
                    l.SyntaxError(fmt.Sprintf(`extend type %q not found`, obj.Name))
                }
                origin, ok := old.(*Object)
                if !ok {
                    l.SyntaxError(fmt.Sprintf(`extend type %q must be object, but found %q`, obj.Name, old.Kind()))
                }
                origin.Fields = append(origin.Fields, obj.Fields...)
            default:
                l.SyntaxError(fmt.Sprintf(`unexpected %q, expecting "type"`, t))
            }

add this to schema.go, and it works, maybe the extend type should be tracked in Object, can do the same for interface or input, very interesting.

I also suggest support extend <type> <ObjectName> by <ObjectName>.
Because, I we always define types for different module

type AQuery{
doA():A
}
type BQuery{
doB():B
}

# If we want to enable the module
extend type Query by AQuery

Very useful for real word usage. I will try to do this in my own fork.

This syntax is implemented in goaphql, and several other very useful syntax.

For bigger scale use, I think how to construct the schema is become more important, some syntax like this become very useful.

# file core.graphqls - basic difinitions

scalar Date
scalar Html

directive @role(name:String!)

# file user.graphqls - api for user
type UserQuery{}
type UserMutation{}

schema User{
    query: UserQuery
    mutation: UserMutation
}

# file admin.graphqls - api for amdin
type AdminQuery{}
type AdminMutation{}

schema Admin{
    query: AdminQuery
    mutation: AdminMutation
}

# file crm.graphqls - crm app
type CrmQuery{}
type CrmMutation{}

type CrmAdminQuery{}
type CrmAdminMutation{}

extend UserQuery by CrmQuery
extend UserMutation by CrmMutation

extend CrmAdminQuery by AdminQuery
extend CrmAdminMutation by AdminMutation

# file cms.graphqls - cms app
# file ecom.graphqls - ecom app

For different developer and team to build rich api, this what I'm doing now. 馃槂

Is there any plan to officially support the extend features soon?

Yes, since extend has made it's way into the specification working draft, we should plan on implementing support for type extension functionality.

I've added an item to track this in the roadmap.

@tonyghita how about use a antlr based parser, https://github.com/wenerme/goaphql/tree/master/gqlp easy to add more features, I also implement the same parser in java https://github.com/wenerme/jraphql/tree/master/jraphql-graphql-java-adapter . easy to use the same grammar for multi language.

I think we'll have to change the parser to gain the flexibility we need to keep up with the draft specification.

I'm not familiar with ANTLR. I'll take a look.

I've started work on a new lexer/parser combo that uses a customer scanner built (rather than the text/scanner meant for parsing Go source) that seems really promising.

I hope to have those changes out by next week with full parity on the existing parser and additional support for block strings and descriptions to start.

This should be able to be closed since #345 has been merged?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tonyghita picture tonyghita  路  3Comments

aquiseb picture aquiseb  路  4Comments

bsr203 picture bsr203  路  6Comments

JitinGuglani picture JitinGuglani  路  6Comments

estutzenberger picture estutzenberger  路  4Comments