Skip to content

Commit 25e8656

Browse files
pavelnikolovKNiepok
authored andcommitted
Allow directives on schema (graph-gophers#585)
1 parent 7ddb8a6 commit 25e8656

File tree

4 files changed

+341
-15
lines changed

4 files changed

+341
-15
lines changed

ast/schema.go

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package ast
22

3+
import "github.com/graph-gophers/graphql-go/errors"
4+
35
// Schema represents a GraphQL service's collective type system capabilities.
46
// A schema is defined in terms of the types and directives it supports as well as the root
57
// operation types for each kind of operation: `query`, `mutation`, and `subscription`.
@@ -8,12 +10,8 @@ package ast
810
//
911
// http://spec.graphql.org/draft/#sec-Schema
1012
type Schema struct {
11-
// RootOperationTypes determines the place in the type system where `query`, `mutation`, and
12-
// `subscription` operations begin.
13-
//
14-
// http://spec.graphql.org/draft/#sec-Root-Operation-Types
15-
//
16-
RootOperationTypes map[string]NamedType
13+
// SchemaDefinition corresponds to the `schema` sdl keyword.
14+
SchemaDefinition
1715

1816
// Types are the fundamental unit of any GraphQL schema.
1917
// There are six kinds of named type definitions in GraphQL, and two wrapping types.
@@ -28,14 +26,71 @@ type Schema struct {
2826
// http://spec.graphql.org/#sec-Type-System.Directives
2927
Directives map[string]*DirectiveDefinition
3028

31-
EntryPointNames map[string]string
32-
Objects []*ObjectTypeDefinition
33-
Unions []*Union
34-
Enums []*EnumTypeDefinition
35-
Extensions []*Extension
36-
SchemaString string
29+
Objects []*ObjectTypeDefinition
30+
Unions []*Union
31+
Enums []*EnumTypeDefinition
32+
Extensions []*Extension
33+
SchemaString string
3734
}
3835

3936
func (s *Schema) Resolve(name string) Type {
4037
return s.Types[name]
4138
}
39+
40+
// SchemaDefinition is an optional schema block.
41+
// If the schema definition is present it might contain a description and directives. It also contains a map of root operations. For example:
42+
//
43+
// schema {
44+
// query: Query
45+
// mutation: Mutation
46+
// subscription: Subscription
47+
// }
48+
//
49+
// type Query {
50+
// # query fields go here
51+
// }
52+
//
53+
// type Mutation {
54+
// # mutation fields go here
55+
// }
56+
//
57+
// type Subscription {
58+
// # subscription fields go here
59+
// }
60+
//
61+
// If the root operations have default names (i.e. Query, Mutation and Subscription), then the schema definition can be omitted. For example, this is equivalent to the above schema:
62+
//
63+
// type Query {
64+
// # query fields go here
65+
// }
66+
//
67+
// type Mutation {
68+
// # mutation fields go here
69+
// }
70+
//
71+
// type Subscription {
72+
// # subscription fields go here
73+
// }
74+
//
75+
// https://spec.graphql.org/October2021/#sec-Schema
76+
type SchemaDefinition struct {
77+
// Present is true if the schema definition is not omitted, false otherwise. For example, in the following schema
78+
//
79+
// type Query {
80+
// hello: String!
81+
// }
82+
//
83+
// the schema keyword is omitted since the default name for Query is used. In that case Present would be false.
84+
Present bool
85+
86+
// RootOperationTypes determines the place in the type system where `query`, `mutation`, and
87+
// `subscription` operations begin.
88+
//
89+
// http://spec.graphql.org/draft/#sec-Root-Operation-Types
90+
RootOperationTypes map[string]NamedType
91+
92+
EntryPointNames map[string]string
93+
Desc string
94+
Directives DirectiveList
95+
Loc errors.Location
96+
}

examples_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ func (s Season) String() string {
292292
panic("unreachable")
293293
}
294294
`
295+
295296
funcs := template.FuncMap{
296297
"toVar": func(s string) string {
297298
if len(s) == 0 {
@@ -300,6 +301,7 @@ func (s Season) String() string {
300301
return strings.ToUpper(s[:1]) + strings.ToLower(s[1:])
301302
},
302303
}
304+
303305
tpl, err := template.New("enum").Funcs(funcs).Parse(gocode)
304306
if err != nil {
305307
panic(err)

internal/schema/schema.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ import (
1212
// New initializes an instance of Schema.
1313
func New() *ast.Schema {
1414
s := &ast.Schema{
15-
EntryPointNames: make(map[string]string),
16-
Types: make(map[string]ast.NamedType),
17-
Directives: make(map[string]*ast.DirectiveDefinition),
15+
SchemaDefinition: ast.SchemaDefinition{
16+
EntryPointNames: make(map[string]string),
17+
},
18+
Types: make(map[string]ast.NamedType),
19+
Directives: make(map[string]*ast.DirectiveDefinition),
1820
}
1921
m := newMeta()
2022
for n, t := range m.Types {
@@ -362,6 +364,10 @@ func parseSchema(s *ast.Schema, l *common.Lexer) {
362364
switch x := l.ConsumeIdent(); x {
363365

364366
case "schema":
367+
s.SchemaDefinition.Present = true
368+
s.SchemaDefinition.Loc = l.Location()
369+
s.SchemaDefinition.Desc = desc
370+
s.SchemaDefinition.Directives = common.ParseDirectives(l)
365371
l.ConsumeToken('{')
366372
for l.Peek() != '}' {
367373

@@ -565,6 +571,8 @@ func parseExtension(s *ast.Schema, l *common.Lexer) {
565571
switch x := l.ConsumeIdent(); x {
566572
case "schema":
567573
l.ConsumeToken('{')
574+
s.SchemaDefinition.Present = true
575+
s.SchemaDefinition.Directives = append(s.SchemaDefinition.Directives, common.ParseDirectives(l)...)
568576
for l.Peek() != '}' {
569577
name := l.ConsumeIdent()
570578
l.ConsumeToken(':')

0 commit comments

Comments
 (0)