├── .gitignore
├── js
├── routes
│ └── AppHomeRoute.js
├── app.js
└── components
│ └── App.js
├── public
└── index.html
├── graphql.go
├── package.json
├── server.js
├── scripts
└── updateSchema.go
├── data
├── database.go
├── schema.go
└── schema.json
├── PATENTS
├── README.md
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | npm-debug.log
4 | data/schema.graphql
--------------------------------------------------------------------------------
/js/routes/AppHomeRoute.js:
--------------------------------------------------------------------------------
1 | import Relay from 'react-relay';
2 |
3 | export default class extends Relay.Route {
4 | static queries = {
5 | viewer: () => Relay.QL`
6 | query {
7 | viewer
8 | }
9 | `,
10 | };
11 | static routeName = 'AppHomeRoute';
12 | }
13 |
--------------------------------------------------------------------------------
/js/app.js:
--------------------------------------------------------------------------------
1 | import 'babel/polyfill';
2 |
3 | import App from './components/App';
4 | import AppHomeRoute from './routes/AppHomeRoute';
5 | import React from 'react';
6 | import ReactDOM from 'react-dom';
7 | import Relay from 'react-relay';
8 |
9 | ReactDOM.render(
10 | ,
14 | document.getElementById('root')
15 | );
16 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Relay • Starter Kit
7 |
8 |
9 |
10 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/graphql.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/graphql-go/handler"
5 | "github.com/sogko/golang-relay-starter-kit/data"
6 | "log"
7 | "net/http"
8 | )
9 |
10 | func main() {
11 |
12 | // simplest relay-compliant graphql server HTTP handler
13 | h := handler.New(&handler.Config{
14 | Schema: &data.Schema,
15 | Pretty: true,
16 | })
17 |
18 | // create graphql endpoint
19 | http.Handle("/graphql", h)
20 |
21 | // serve!
22 | port := ":8080"
23 | log.Printf(`GraphQL server starting up on http://localhost%v`, port)
24 | err := http.ListenAndServe(port, nil)
25 | if err != nil {
26 | log.Fatalf("ListenAndServe failed, %v", err)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "golang-relay-starter-kit",
3 | "private": true,
4 | "description": "A quick way to get up and running with Relay on Golang",
5 | "repository": "github.com/sogko/golang-relay-starter-kit",
6 | "version": "0.1.0",
7 | "scripts": {
8 | "start": "go run graphql.go & babel-node ./server.js",
9 | "update-schema": "cd ./scripts && go run updateSchema.go"
10 | },
11 | "dependencies": {
12 | "babel": "5.8.21",
13 | "babel-loader": "5.3.2",
14 | "babel-relay-plugin": "0.2.3",
15 | "classnames": "^2.1.3",
16 | "express": "^4.13.1",
17 | "react": "^0.14.0-rc",
18 | "react-dom": "^0.14.0-rc",
19 | "react-relay": "^0.3.1",
20 | "webpack": "^1.10.5",
21 | "webpack-dev-server": "^1.10.1"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/js/components/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Relay from 'react-relay';
3 |
4 | class App extends React.Component {
5 | render() {
6 | return (
7 |
8 |
Widget list
9 |
10 | {this.props.viewer.widgets.edges.map(edge =>
11 | - {edge.node.name} (ID: {edge.node.id})
12 | )}
13 |
14 |
15 | );
16 | }
17 | }
18 |
19 | export default Relay.createContainer(App, {
20 | fragments: {
21 | viewer: () => Relay.QL`
22 | fragment on User {
23 | widgets(first: 10) {
24 | edges {
25 | node {
26 | id,
27 | name,
28 | },
29 | },
30 | },
31 | }
32 | `,
33 | },
34 | });
35 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import path from 'path';
3 | import webpack from 'webpack';
4 | import WebpackDevServer from 'webpack-dev-server';
5 |
6 | const APP_PORT = 3000;
7 | const GRAPHQL_PORT = 8080;
8 |
9 | // Serve the Relay app
10 | var compiler = webpack({
11 | entry: path.resolve(__dirname, 'js', 'app.js'),
12 | module: {
13 | loaders: [
14 | {
15 | exclude: /node_modules/,
16 | loader: 'babel',
17 | query: {stage: 0, plugins: ['./build/babelRelayPlugin']},
18 | test: /\.js$/
19 | }
20 | ]
21 | },
22 | output: {filename: 'app.js', path: '/'}
23 | });
24 | var app = new WebpackDevServer(compiler, {
25 | contentBase: '/public/',
26 | proxy: {'/graphql': `http://localhost:${GRAPHQL_PORT}`},
27 | publicPath: '/js/',
28 | stats: {colors: true}
29 | });
30 | // Serve static resources
31 | app.use('/', express.static(path.resolve(__dirname, 'public')));
32 | app.listen(APP_PORT, () => {
33 | console.log(`App is now running on http://localhost:${APP_PORT}`);
34 | });
35 |
--------------------------------------------------------------------------------
/scripts/updateSchema.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "github.com/graphql-go/graphql"
6 | "github.com/graphql-go/graphql/testutil"
7 | "github.com/sogko/golang-relay-starter-kit/data"
8 | "io/ioutil"
9 | "log"
10 | "os"
11 | )
12 |
13 | func main() {
14 | // Save JSON of full schema introspection for Babel Relay Plugin to use
15 | result := graphql.Do(graphql.Params{
16 | Schema: data.Schema,
17 | RequestString: testutil.IntrospectionQuery,
18 | })
19 | if result.HasErrors() {
20 | log.Fatalf("ERROR introspecting schema: %v", result.Errors)
21 | return
22 | } else {
23 | b, err := json.MarshalIndent(result, "", " ")
24 | if err != nil {
25 | log.Fatalf("ERROR: %v", err)
26 | }
27 | err = ioutil.WriteFile("../data/schema.json", b, os.ModePerm)
28 | if err != nil {
29 | log.Fatalf("ERROR: %v", err)
30 | }
31 |
32 | }
33 | // TODO: Save user readable type system shorthand of schema
34 | // pending implementation of printSchema
35 | /*
36 | fs.writeFileSync(
37 | path.join(__dirname, '../data/schema.graphql'),
38 | printSchema(Schema)
39 | );
40 | */
41 | }
42 |
--------------------------------------------------------------------------------
/data/database.go:
--------------------------------------------------------------------------------
1 | package data
2 |
3 | // Model structs
4 | type User struct {
5 | Id string `json:"id"`
6 | Name string `json:"name"`
7 | Widgets []*Widget `json:"widgets"`
8 | }
9 |
10 | type Widget struct {
11 | Id string `json:"id"`
12 | Name string `json:"name"`
13 | }
14 |
15 | // Mock data
16 | var viewer = &User{
17 | Id: "1",
18 | Name: "Anonymous",
19 | }
20 | var widgets = []*Widget{
21 | &Widget{"0", "What's-it"},
22 | &Widget{"1", "Who's-it"},
23 | &Widget{"2", "How's-it"},
24 | }
25 |
26 | // Data accessors
27 | func GetUser(id string) *User {
28 | if id == viewer.Id {
29 | return viewer
30 | }
31 | return nil
32 | }
33 | func GetViewer() *User {
34 | return viewer
35 | }
36 | func GetWidget(id string) *Widget {
37 | for _, widget := range widgets {
38 | if widget.Id == id {
39 | return widget
40 | }
41 | }
42 | return nil
43 | }
44 | func GetWidgets() []*Widget {
45 | return widgets
46 | }
47 | func WidgetsToInterfaceSlice(widgets ...*Widget) []interface{} {
48 | var interfaceSlice []interface{} = make([]interface{}, len(widgets))
49 | for i, d := range widgets {
50 | interfaceSlice[i] = d
51 | }
52 | return interfaceSlice
53 | }
54 |
--------------------------------------------------------------------------------
/PATENTS:
--------------------------------------------------------------------------------
1 | Additional Grant of Patent Rights Version 2
2 |
3 | "Software" means the Relay Starter Kit software distributed by Facebook, Inc.
4 |
5 | Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software
6 | ("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable
7 | (subject to the termination provision below) license under any Necessary
8 | Claims, to make, have made, use, sell, offer to sell, import, and otherwise
9 | transfer the Software. For avoidance of doubt, no license is granted under
10 | Facebook's rights in any patent claims that are infringed by (i) modifications
11 | to the Software made by you or any third party or (ii) the Software in
12 | combination with any software or other technology.
13 |
14 | The license granted hereunder will terminate, automatically and without notice,
15 | if you (or any of your subsidiaries, corporate affiliates or agents) initiate
16 | directly or indirectly, or take a direct financial interest in, any Patent
17 | Assertion: (i) against Facebook or any of its subsidiaries or corporate
18 | affiliates, (ii) against any party if such Patent Assertion arises in whole or
19 | in part from any software, technology, product or service of Facebook or any of
20 | its subsidiaries or corporate affiliates, or (iii) against any party relating
21 | to the Software. Notwithstanding the foregoing, if Facebook or any of its
22 | subsidiaries or corporate affiliates files a lawsuit alleging patent
23 | infringement against you in the first instance, and you respond by filing a
24 | patent infringement counterclaim in that lawsuit against that party that is
25 | unrelated to the Software, the license granted hereunder will not terminate
26 | under section (i) of this paragraph due to such counterclaim.
27 |
28 | A "Necessary Claim" is a claim of a patent owned by Facebook that is
29 | necessarily infringed by the Software standing alone.
30 |
31 | A "Patent Assertion" is any lawsuit or other action alleging direct, indirect,
32 | or contributory infringement or inducement to infringe any patent, including a
33 | cross-claim or counterclaim.
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Golang-Relay Starter Kit
2 |
3 | This kit includes:
4 | - a **NodeJS** app server: to serve the front-end written with `react-relay`
5 | - a **Golang** GraphQL server: to serve the back-end `graphql-go` server that handles GraphQL queries
6 | - a Babel transpiler workflow using `webpack` that you can use to get started building an app with Relay.
7 |
8 | For a walkthrough, see the [Relay tutorial](https://facebook.github.io/relay/docs/tutorial.html).
9 |
10 | ### Notes:
11 | This is based on alpha version of `graphql-go` and `graphql-relay-go`.
12 | Be sure to watch both repositories for latest changes.
13 |
14 | ## Installation
15 |
16 | - Install dependencies for NodeJS app server
17 | ```
18 | npm install
19 | ```
20 | - Install dependencies for Golang GraphQL server
21 | ```
22 | go get -v
23 | ```
24 |
25 | ## Running
26 |
27 | Start a local server:
28 |
29 | ```
30 | npm start
31 | ```
32 |
33 | The above command will run both the NodeJS app server and Golang GraphQL server concurrently.
34 |
35 | - Golang GraphQL server will be running at http://localhost:8080/graphql
36 | - NodeJS app server will be running at http://localhost:3000
37 |
38 | ## Developing
39 |
40 | ### JavaScript
41 | Any changes you make to files in the `js/` directory will cause the server to
42 | automatically rebuild the app and refresh your browser.
43 |
44 | ### Golang
45 |
46 | #### Schema data
47 | Since Golang does not support loading package / module dynamically, remember to update the package import for schema data in:
48 | - `graphql.go`
49 | - `scripts/updateSchema.go`
50 |
51 | For e.g
52 |
53 | ```go
54 | import (
55 | ...
56 | "github.com/sogko/golang-relay-starter-kit/data" // <--- update to package containing schema
57 | )
58 | ```
59 |
60 | #### Schema updates
61 | If at any time you make changes to `data/schema.go`, stop the server,
62 | regenerate `data/schema.json`, and restart the server:
63 |
64 | ```
65 | npm run update-schema
66 | npm start
67 | ```
68 |
69 | `schema.json` is needed by the JS code for `./build/babelRelayPlugin.js`
70 |
71 | ## Examples
72 | - [todomvc-relay-go](https://github.com/sogko/todomvc-relay-go) - Port of the React/Relay TodoMVC app, driven by a Golang GraphQL backend
73 |
74 | Feel free to submit a PR to add to this list.
75 |
76 | ## TODOs
77 | - [x] Swap out `express-graphql` server with a Golang GraphQL server
78 | - [x] GraphQL schema definition in Golang
79 | - [x] Generate `schema.json` from schema definition for `babel-relay-plugin`
80 | - [ ] Generate `schema.graphql` from schema definition
81 |
82 | ## Credits
83 | This kit is build on top of https://github.com/relayjs/relay-starter-kit
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Hafiz Ismail
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 | ---
24 |
25 | BSD License
26 |
27 | For Relay Starter Kit software
28 |
29 | Copyright (c) 2013-2015, Facebook, Inc.
30 | All rights reserved.
31 |
32 | Redistribution and use in source and binary forms, with or without modification,
33 | are permitted provided that the following conditions are met:
34 |
35 | * Redistributions of source code must retain the above copyright notice, this
36 | list of conditions and the following disclaimer.
37 |
38 | * Redistributions in binary form must reproduce the above copyright notice,
39 | this list of conditions and the following disclaimer in the documentation
40 | and/or other materials provided with the distribution.
41 |
42 | * Neither the name Facebook nor the names of its contributors may be used to
43 | endorse or promote products derived from this software without specific
44 | prior written permission.
45 |
46 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
47 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
50 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
53 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
54 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
55 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 |
--------------------------------------------------------------------------------
/data/schema.go:
--------------------------------------------------------------------------------
1 | package data
2 |
3 | import (
4 | "github.com/graphql-go/graphql"
5 | "github.com/graphql-go/relay"
6 | "golang.org/x/net/context"
7 | )
8 |
9 | var userType *graphql.Object
10 | var widgetType *graphql.Object
11 |
12 | var nodeDefinitions *relay.NodeDefinitions
13 | var widgetConnection *relay.GraphQLConnectionDefinitions
14 |
15 | var Schema graphql.Schema
16 |
17 | func init() {
18 |
19 | /**
20 | * We get the node interface and field from the Relay library.
21 | *
22 | * The first method defines the way we resolve an ID to its object.
23 | * The second defines the way we resolve an object to its GraphQL type.
24 | */
25 | nodeDefinitions = relay.NewNodeDefinitions(relay.NodeDefinitionsConfig{
26 | IDFetcher: func(id string, info graphql.ResolveInfo, ct context.Context) (interface{}, error) {
27 | resolvedID := relay.FromGlobalID(id)
28 | if resolvedID.Type == "User" {
29 | return GetUser(resolvedID.ID), nil
30 | }
31 | if resolvedID.Type == "Widget" {
32 | return GetWidget(resolvedID.ID), nil
33 | }
34 | return nil, nil
35 | },
36 | TypeResolve: func(value interface{}, info graphql.ResolveInfo) *graphql.Object {
37 | switch value.(type) {
38 | case *User:
39 | return userType
40 | case *Widget:
41 | return widgetType
42 | }
43 | return nil
44 | },
45 | })
46 |
47 | /**
48 | * Define your own types here
49 | */
50 | widgetType = graphql.NewObject(graphql.ObjectConfig{
51 | Name: "Widget",
52 | Description: "A shiny widget'",
53 | Fields: graphql.Fields{
54 | "id": relay.GlobalIDField("Widget", nil),
55 | "name": &graphql.Field{
56 | Description: "The name of the widget",
57 | Type: graphql.String,
58 | },
59 | },
60 | Interfaces: []*graphql.Interface{
61 | nodeDefinitions.NodeInterface,
62 | },
63 | })
64 | widgetConnection = relay.ConnectionDefinitions(relay.ConnectionConfig{
65 | Name: "WidgetConnection",
66 | NodeType: widgetType,
67 | })
68 |
69 | userType = graphql.NewObject(graphql.ObjectConfig{
70 | Name: "User",
71 | Description: "A person who uses our app",
72 | Fields: graphql.Fields{
73 | "id": relay.GlobalIDField("User", nil),
74 | "widgets": &graphql.Field{
75 | Type: widgetConnection.ConnectionType,
76 | Description: "A person's collection of widgets",
77 | Args: relay.ConnectionArgs,
78 | Resolve: func(p graphql.ResolveParams) (interface{}, error) {
79 | args := relay.NewConnectionArguments(p.Args)
80 | dataSlice := WidgetsToInterfaceSlice(GetWidgets()...)
81 | return relay.ConnectionFromArray(dataSlice, args), nil
82 | },
83 | },
84 | },
85 | Interfaces: []*graphql.Interface{
86 | nodeDefinitions.NodeInterface,
87 | },
88 | })
89 |
90 | /**
91 | * This is the type that will be the root of our query,
92 | * and the entry point into our schema.
93 | */
94 | queryType := graphql.NewObject(graphql.ObjectConfig{
95 | Name: "Query",
96 | Fields: graphql.Fields{
97 | "node": nodeDefinitions.NodeField,
98 |
99 | // Add you own root fields here
100 | "viewer": &graphql.Field{
101 | Type: userType,
102 | Resolve: func(p graphql.ResolveParams) (interface{}, error) {
103 | return GetViewer(), nil
104 | },
105 | },
106 | },
107 | })
108 |
109 | /**
110 | * This is the type that will be the root of our mutations,
111 | * and the entry point into performing writes in our schema.
112 | */
113 | // mutationType := graphql.NewObject(graphql.ObjectConfig{
114 | // Name: "Mutation",
115 | // Fields: graphql.Fields{
116 | // // Add you own mutations here
117 | // },
118 | // })
119 |
120 | /**
121 | * Finally, we construct our schema (whose starting query type is the query
122 | * type we defined above) and export it.
123 | */
124 | var err error
125 | Schema, err = graphql.NewSchema(graphql.SchemaConfig{
126 | Query: queryType,
127 | })
128 | if err != nil {
129 | panic(err)
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/data/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "__schema": {
4 | "directives": [
5 | {
6 | "args": [
7 | {
8 | "defaultValue": null,
9 | "description": "Included when true.",
10 | "name": "if",
11 | "type": {
12 | "kind": "NON_NULL",
13 | "name": null,
14 | "ofType": {
15 | "kind": "SCALAR",
16 | "name": "Boolean",
17 | "ofType": null
18 | }
19 | }
20 | }
21 | ],
22 | "description": "Directs the executor to include this field or fragment only when the `if` argument is true.",
23 | "name": "include",
24 | "onField": true,
25 | "onFragment": true,
26 | "onOperation": false
27 | },
28 | {
29 | "args": [
30 | {
31 | "defaultValue": null,
32 | "description": "Skipped when true.",
33 | "name": "if",
34 | "type": {
35 | "kind": "NON_NULL",
36 | "name": null,
37 | "ofType": {
38 | "kind": "SCALAR",
39 | "name": "Boolean",
40 | "ofType": null
41 | }
42 | }
43 | }
44 | ],
45 | "description": "Directs the executor to skip this field or fragment when the `if` argument is true.",
46 | "name": "skip",
47 | "onField": true,
48 | "onFragment": true,
49 | "onOperation": false
50 | }
51 | ],
52 | "mutationType": null,
53 | "queryType": {
54 | "name": "Query"
55 | },
56 | "types": [
57 | {
58 | "description": null,
59 | "enumValues": null,
60 | "fields": null,
61 | "inputFields": null,
62 | "interfaces": null,
63 | "kind": "SCALAR",
64 | "name": "ID",
65 | "possibleTypes": null
66 | },
67 | {
68 | "description": "A GraphQL Schema defines the capabilities of a GraphQL\nserver. It exposes all available types and directives on\nthe server, as well as the entry points for query and\nmutation operations.",
69 | "enumValues": null,
70 | "fields": [
71 | {
72 | "args": [],
73 | "deprecationReason": null,
74 | "description": "The type that query operations will be rooted at.",
75 | "isDeprecated": false,
76 | "name": "queryType",
77 | "type": {
78 | "kind": "NON_NULL",
79 | "name": null,
80 | "ofType": {
81 | "kind": "OBJECT",
82 | "name": "__Type",
83 | "ofType": null
84 | }
85 | }
86 | },
87 | {
88 | "args": [],
89 | "deprecationReason": null,
90 | "description": "If this server supports mutation, the type that mutation operations will be rooted at.",
91 | "isDeprecated": false,
92 | "name": "mutationType",
93 | "type": {
94 | "kind": "OBJECT",
95 | "name": "__Type",
96 | "ofType": null
97 | }
98 | },
99 | {
100 | "args": [],
101 | "deprecationReason": null,
102 | "description": "A list of all directives supported by this server.",
103 | "isDeprecated": false,
104 | "name": "directives",
105 | "type": {
106 | "kind": "NON_NULL",
107 | "name": null,
108 | "ofType": {
109 | "kind": "LIST",
110 | "name": null,
111 | "ofType": {
112 | "kind": "NON_NULL",
113 | "name": null,
114 | "ofType": {
115 | "kind": "OBJECT",
116 | "name": "__Directive"
117 | }
118 | }
119 | }
120 | }
121 | },
122 | {
123 | "args": [],
124 | "deprecationReason": null,
125 | "description": "A list of all types supported by this server.",
126 | "isDeprecated": false,
127 | "name": "types",
128 | "type": {
129 | "kind": "NON_NULL",
130 | "name": null,
131 | "ofType": {
132 | "kind": "LIST",
133 | "name": null,
134 | "ofType": {
135 | "kind": "NON_NULL",
136 | "name": null,
137 | "ofType": {
138 | "kind": "OBJECT",
139 | "name": "__Type"
140 | }
141 | }
142 | }
143 | }
144 | }
145 | ],
146 | "inputFields": null,
147 | "interfaces": [],
148 | "kind": "OBJECT",
149 | "name": "__Schema",
150 | "possibleTypes": null
151 | },
152 | {
153 | "description": null,
154 | "enumValues": null,
155 | "fields": [
156 | {
157 | "args": [],
158 | "deprecationReason": null,
159 | "description": null,
160 | "isDeprecated": false,
161 | "name": "name",
162 | "type": {
163 | "kind": "NON_NULL",
164 | "name": null,
165 | "ofType": {
166 | "kind": "SCALAR",
167 | "name": "String",
168 | "ofType": null
169 | }
170 | }
171 | },
172 | {
173 | "args": [],
174 | "deprecationReason": null,
175 | "description": null,
176 | "isDeprecated": false,
177 | "name": "description",
178 | "type": {
179 | "kind": "SCALAR",
180 | "name": "String",
181 | "ofType": null
182 | }
183 | },
184 | {
185 | "args": [],
186 | "deprecationReason": null,
187 | "description": null,
188 | "isDeprecated": false,
189 | "name": "args",
190 | "type": {
191 | "kind": "NON_NULL",
192 | "name": null,
193 | "ofType": {
194 | "kind": "LIST",
195 | "name": null,
196 | "ofType": {
197 | "kind": "NON_NULL",
198 | "name": null,
199 | "ofType": {
200 | "kind": "OBJECT",
201 | "name": "__InputValue"
202 | }
203 | }
204 | }
205 | }
206 | },
207 | {
208 | "args": [],
209 | "deprecationReason": null,
210 | "description": null,
211 | "isDeprecated": false,
212 | "name": "onOperation",
213 | "type": {
214 | "kind": "NON_NULL",
215 | "name": null,
216 | "ofType": {
217 | "kind": "SCALAR",
218 | "name": "Boolean",
219 | "ofType": null
220 | }
221 | }
222 | },
223 | {
224 | "args": [],
225 | "deprecationReason": null,
226 | "description": null,
227 | "isDeprecated": false,
228 | "name": "onFragment",
229 | "type": {
230 | "kind": "NON_NULL",
231 | "name": null,
232 | "ofType": {
233 | "kind": "SCALAR",
234 | "name": "Boolean",
235 | "ofType": null
236 | }
237 | }
238 | },
239 | {
240 | "args": [],
241 | "deprecationReason": null,
242 | "description": null,
243 | "isDeprecated": false,
244 | "name": "onField",
245 | "type": {
246 | "kind": "NON_NULL",
247 | "name": null,
248 | "ofType": {
249 | "kind": "SCALAR",
250 | "name": "Boolean",
251 | "ofType": null
252 | }
253 | }
254 | }
255 | ],
256 | "inputFields": null,
257 | "interfaces": [],
258 | "kind": "OBJECT",
259 | "name": "__Directive",
260 | "possibleTypes": null
261 | },
262 | {
263 | "description": null,
264 | "enumValues": null,
265 | "fields": null,
266 | "inputFields": null,
267 | "interfaces": null,
268 | "kind": "SCALAR",
269 | "name": "Boolean",
270 | "possibleTypes": null
271 | },
272 | {
273 | "description": null,
274 | "enumValues": null,
275 | "fields": [
276 | {
277 | "args": [],
278 | "deprecationReason": null,
279 | "description": null,
280 | "isDeprecated": false,
281 | "name": "deprecationReason",
282 | "type": {
283 | "kind": "SCALAR",
284 | "name": "String",
285 | "ofType": null
286 | }
287 | },
288 | {
289 | "args": [],
290 | "deprecationReason": null,
291 | "description": null,
292 | "isDeprecated": false,
293 | "name": "name",
294 | "type": {
295 | "kind": "NON_NULL",
296 | "name": null,
297 | "ofType": {
298 | "kind": "SCALAR",
299 | "name": "String",
300 | "ofType": null
301 | }
302 | }
303 | },
304 | {
305 | "args": [],
306 | "deprecationReason": null,
307 | "description": null,
308 | "isDeprecated": false,
309 | "name": "description",
310 | "type": {
311 | "kind": "SCALAR",
312 | "name": "String",
313 | "ofType": null
314 | }
315 | },
316 | {
317 | "args": [],
318 | "deprecationReason": null,
319 | "description": null,
320 | "isDeprecated": false,
321 | "name": "isDeprecated",
322 | "type": {
323 | "kind": "NON_NULL",
324 | "name": null,
325 | "ofType": {
326 | "kind": "SCALAR",
327 | "name": "Boolean",
328 | "ofType": null
329 | }
330 | }
331 | }
332 | ],
333 | "inputFields": null,
334 | "interfaces": [],
335 | "kind": "OBJECT",
336 | "name": "__EnumValue",
337 | "possibleTypes": null
338 | },
339 | {
340 | "description": null,
341 | "enumValues": null,
342 | "fields": [
343 | {
344 | "args": [],
345 | "deprecationReason": null,
346 | "description": null,
347 | "isDeprecated": false,
348 | "name": "description",
349 | "type": {
350 | "kind": "SCALAR",
351 | "name": "String",
352 | "ofType": null
353 | }
354 | },
355 | {
356 | "args": [],
357 | "deprecationReason": null,
358 | "description": null,
359 | "isDeprecated": false,
360 | "name": "args",
361 | "type": {
362 | "kind": "NON_NULL",
363 | "name": null,
364 | "ofType": {
365 | "kind": "LIST",
366 | "name": null,
367 | "ofType": {
368 | "kind": "NON_NULL",
369 | "name": null,
370 | "ofType": {
371 | "kind": "OBJECT",
372 | "name": "__InputValue"
373 | }
374 | }
375 | }
376 | }
377 | },
378 | {
379 | "args": [],
380 | "deprecationReason": null,
381 | "description": null,
382 | "isDeprecated": false,
383 | "name": "type",
384 | "type": {
385 | "kind": "NON_NULL",
386 | "name": null,
387 | "ofType": {
388 | "kind": "OBJECT",
389 | "name": "__Type",
390 | "ofType": null
391 | }
392 | }
393 | },
394 | {
395 | "args": [],
396 | "deprecationReason": null,
397 | "description": null,
398 | "isDeprecated": false,
399 | "name": "isDeprecated",
400 | "type": {
401 | "kind": "NON_NULL",
402 | "name": null,
403 | "ofType": {
404 | "kind": "SCALAR",
405 | "name": "Boolean",
406 | "ofType": null
407 | }
408 | }
409 | },
410 | {
411 | "args": [],
412 | "deprecationReason": null,
413 | "description": null,
414 | "isDeprecated": false,
415 | "name": "deprecationReason",
416 | "type": {
417 | "kind": "SCALAR",
418 | "name": "String",
419 | "ofType": null
420 | }
421 | },
422 | {
423 | "args": [],
424 | "deprecationReason": null,
425 | "description": null,
426 | "isDeprecated": false,
427 | "name": "name",
428 | "type": {
429 | "kind": "NON_NULL",
430 | "name": null,
431 | "ofType": {
432 | "kind": "SCALAR",
433 | "name": "String",
434 | "ofType": null
435 | }
436 | }
437 | }
438 | ],
439 | "inputFields": null,
440 | "interfaces": [],
441 | "kind": "OBJECT",
442 | "name": "__Field",
443 | "possibleTypes": null
444 | },
445 | {
446 | "description": "Information about pagination in a connection.",
447 | "enumValues": null,
448 | "fields": [
449 | {
450 | "args": [],
451 | "deprecationReason": null,
452 | "description": "When paginating forwards, are there more items?",
453 | "isDeprecated": false,
454 | "name": "hasNextPage",
455 | "type": {
456 | "kind": "NON_NULL",
457 | "name": null,
458 | "ofType": {
459 | "kind": "SCALAR",
460 | "name": "Boolean",
461 | "ofType": null
462 | }
463 | }
464 | },
465 | {
466 | "args": [],
467 | "deprecationReason": null,
468 | "description": "When paginating backwards, are there more items?",
469 | "isDeprecated": false,
470 | "name": "hasPreviousPage",
471 | "type": {
472 | "kind": "NON_NULL",
473 | "name": null,
474 | "ofType": {
475 | "kind": "SCALAR",
476 | "name": "Boolean",
477 | "ofType": null
478 | }
479 | }
480 | },
481 | {
482 | "args": [],
483 | "deprecationReason": null,
484 | "description": "When paginating backwards, the cursor to continue.",
485 | "isDeprecated": false,
486 | "name": "startCursor",
487 | "type": {
488 | "kind": "SCALAR",
489 | "name": "String",
490 | "ofType": null
491 | }
492 | },
493 | {
494 | "args": [],
495 | "deprecationReason": null,
496 | "description": "When paginating forwards, the cursor to continue.",
497 | "isDeprecated": false,
498 | "name": "endCursor",
499 | "type": {
500 | "kind": "SCALAR",
501 | "name": "String",
502 | "ofType": null
503 | }
504 | }
505 | ],
506 | "inputFields": null,
507 | "interfaces": [],
508 | "kind": "OBJECT",
509 | "name": "PageInfo",
510 | "possibleTypes": null
511 | },
512 | {
513 | "description": "An edge in a connection",
514 | "enumValues": null,
515 | "fields": [
516 | {
517 | "args": [],
518 | "deprecationReason": null,
519 | "description": "The item at the end of the edge",
520 | "isDeprecated": false,
521 | "name": "node",
522 | "type": {
523 | "kind": "OBJECT",
524 | "name": "Widget",
525 | "ofType": null
526 | }
527 | },
528 | {
529 | "args": [],
530 | "deprecationReason": null,
531 | "description": " cursor for use in pagination",
532 | "isDeprecated": false,
533 | "name": "cursor",
534 | "type": {
535 | "kind": "NON_NULL",
536 | "name": null,
537 | "ofType": {
538 | "kind": "SCALAR",
539 | "name": "String",
540 | "ofType": null
541 | }
542 | }
543 | }
544 | ],
545 | "inputFields": null,
546 | "interfaces": [],
547 | "kind": "OBJECT",
548 | "name": "WidgetConnectionEdge",
549 | "possibleTypes": null
550 | },
551 | {
552 | "description": null,
553 | "enumValues": null,
554 | "fields": [
555 | {
556 | "args": [],
557 | "deprecationReason": null,
558 | "description": null,
559 | "isDeprecated": false,
560 | "name": "name",
561 | "type": {
562 | "kind": "NON_NULL",
563 | "name": null,
564 | "ofType": {
565 | "kind": "SCALAR",
566 | "name": "String",
567 | "ofType": null
568 | }
569 | }
570 | },
571 | {
572 | "args": [],
573 | "deprecationReason": null,
574 | "description": null,
575 | "isDeprecated": false,
576 | "name": "description",
577 | "type": {
578 | "kind": "SCALAR",
579 | "name": "String",
580 | "ofType": null
581 | }
582 | },
583 | {
584 | "args": [],
585 | "deprecationReason": null,
586 | "description": null,
587 | "isDeprecated": false,
588 | "name": "type",
589 | "type": {
590 | "kind": "NON_NULL",
591 | "name": null,
592 | "ofType": {
593 | "kind": "OBJECT",
594 | "name": "__Type",
595 | "ofType": null
596 | }
597 | }
598 | },
599 | {
600 | "args": [],
601 | "deprecationReason": null,
602 | "description": null,
603 | "isDeprecated": false,
604 | "name": "defaultValue",
605 | "type": {
606 | "kind": "SCALAR",
607 | "name": "String",
608 | "ofType": null
609 | }
610 | }
611 | ],
612 | "inputFields": null,
613 | "interfaces": [],
614 | "kind": "OBJECT",
615 | "name": "__InputValue",
616 | "possibleTypes": null
617 | },
618 | {
619 | "description": "An enum describing what kind of type a given __Type is",
620 | "enumValues": [
621 | {
622 | "deprecationReason": null,
623 | "description": "Indicates this type is a scalar.",
624 | "isDeprecated": false,
625 | "name": "SCALAR"
626 | },
627 | {
628 | "deprecationReason": null,
629 | "description": "Indicates this type is an object. `fields` and `interfaces` are valid fields.",
630 | "isDeprecated": false,
631 | "name": "OBJECT"
632 | },
633 | {
634 | "deprecationReason": null,
635 | "description": "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.",
636 | "isDeprecated": false,
637 | "name": "INTERFACE"
638 | },
639 | {
640 | "deprecationReason": null,
641 | "description": "Indicates this type is a union. `possibleTypes` is a valid field.",
642 | "isDeprecated": false,
643 | "name": "UNION"
644 | },
645 | {
646 | "deprecationReason": null,
647 | "description": "Indicates this type is an enum. `enumValues` is a valid field.",
648 | "isDeprecated": false,
649 | "name": "ENUM"
650 | },
651 | {
652 | "deprecationReason": null,
653 | "description": "Indicates this type is an input object. `inputFields` is a valid field.",
654 | "isDeprecated": false,
655 | "name": "INPUT_OBJECT"
656 | },
657 | {
658 | "deprecationReason": null,
659 | "description": "Indicates this type is a list. `ofType` is a valid field.",
660 | "isDeprecated": false,
661 | "name": "LIST"
662 | },
663 | {
664 | "deprecationReason": null,
665 | "description": "Indicates this type is a non-null. `ofType` is a valid field.",
666 | "isDeprecated": false,
667 | "name": "NON_NULL"
668 | }
669 | ],
670 | "fields": null,
671 | "inputFields": null,
672 | "interfaces": null,
673 | "kind": "ENUM",
674 | "name": "__TypeKind",
675 | "possibleTypes": null
676 | },
677 | {
678 | "description": "An object with an ID",
679 | "enumValues": null,
680 | "fields": [
681 | {
682 | "args": [],
683 | "deprecationReason": null,
684 | "description": "The id of the object",
685 | "isDeprecated": false,
686 | "name": "id",
687 | "type": {
688 | "kind": "NON_NULL",
689 | "name": null,
690 | "ofType": {
691 | "kind": "SCALAR",
692 | "name": "ID",
693 | "ofType": null
694 | }
695 | }
696 | }
697 | ],
698 | "inputFields": null,
699 | "interfaces": null,
700 | "kind": "INTERFACE",
701 | "name": "Node",
702 | "possibleTypes": [
703 | {
704 | "kind": "OBJECT",
705 | "name": "Widget",
706 | "ofType": null
707 | },
708 | {
709 | "kind": "OBJECT",
710 | "name": "User",
711 | "ofType": null
712 | }
713 | ]
714 | },
715 | {
716 | "description": null,
717 | "enumValues": null,
718 | "fields": null,
719 | "inputFields": null,
720 | "interfaces": null,
721 | "kind": "SCALAR",
722 | "name": "String",
723 | "possibleTypes": null
724 | },
725 | {
726 | "description": "A connection to a list of items.",
727 | "enumValues": null,
728 | "fields": [
729 | {
730 | "args": [],
731 | "deprecationReason": null,
732 | "description": "Information to aid in pagination.",
733 | "isDeprecated": false,
734 | "name": "pageInfo",
735 | "type": {
736 | "kind": "NON_NULL",
737 | "name": null,
738 | "ofType": {
739 | "kind": "OBJECT",
740 | "name": "PageInfo",
741 | "ofType": null
742 | }
743 | }
744 | },
745 | {
746 | "args": [],
747 | "deprecationReason": null,
748 | "description": "Information to aid in pagination.",
749 | "isDeprecated": false,
750 | "name": "edges",
751 | "type": {
752 | "kind": "LIST",
753 | "name": null,
754 | "ofType": {
755 | "kind": "OBJECT",
756 | "name": "WidgetConnectionEdge",
757 | "ofType": null
758 | }
759 | }
760 | }
761 | ],
762 | "inputFields": null,
763 | "interfaces": [],
764 | "kind": "OBJECT",
765 | "name": "WidgetConnectionConnection",
766 | "possibleTypes": null
767 | },
768 | {
769 | "description": null,
770 | "enumValues": null,
771 | "fields": null,
772 | "inputFields": null,
773 | "interfaces": null,
774 | "kind": "SCALAR",
775 | "name": "Int",
776 | "possibleTypes": null
777 | },
778 | {
779 | "description": null,
780 | "enumValues": null,
781 | "fields": [
782 | {
783 | "args": [],
784 | "deprecationReason": null,
785 | "description": null,
786 | "isDeprecated": false,
787 | "name": "interfaces",
788 | "type": {
789 | "kind": "LIST",
790 | "name": null,
791 | "ofType": {
792 | "kind": "NON_NULL",
793 | "name": null,
794 | "ofType": {
795 | "kind": "OBJECT",
796 | "name": "__Type",
797 | "ofType": null
798 | }
799 | }
800 | }
801 | },
802 | {
803 | "args": [
804 | {
805 | "defaultValue": "false",
806 | "description": null,
807 | "name": "includeDeprecated",
808 | "type": {
809 | "kind": "SCALAR",
810 | "name": "Boolean",
811 | "ofType": null
812 | }
813 | }
814 | ],
815 | "deprecationReason": null,
816 | "description": null,
817 | "isDeprecated": false,
818 | "name": "enumValues",
819 | "type": {
820 | "kind": "LIST",
821 | "name": null,
822 | "ofType": {
823 | "kind": "NON_NULL",
824 | "name": null,
825 | "ofType": {
826 | "kind": "OBJECT",
827 | "name": "__EnumValue",
828 | "ofType": null
829 | }
830 | }
831 | }
832 | },
833 | {
834 | "args": [],
835 | "deprecationReason": null,
836 | "description": null,
837 | "isDeprecated": false,
838 | "name": "description",
839 | "type": {
840 | "kind": "SCALAR",
841 | "name": "String",
842 | "ofType": null
843 | }
844 | },
845 | {
846 | "args": [
847 | {
848 | "defaultValue": "false",
849 | "description": null,
850 | "name": "includeDeprecated",
851 | "type": {
852 | "kind": "SCALAR",
853 | "name": "Boolean",
854 | "ofType": null
855 | }
856 | }
857 | ],
858 | "deprecationReason": null,
859 | "description": null,
860 | "isDeprecated": false,
861 | "name": "fields",
862 | "type": {
863 | "kind": "LIST",
864 | "name": null,
865 | "ofType": {
866 | "kind": "NON_NULL",
867 | "name": null,
868 | "ofType": {
869 | "kind": "OBJECT",
870 | "name": "__Field",
871 | "ofType": null
872 | }
873 | }
874 | }
875 | },
876 | {
877 | "args": [],
878 | "deprecationReason": null,
879 | "description": null,
880 | "isDeprecated": false,
881 | "name": "kind",
882 | "type": {
883 | "kind": "NON_NULL",
884 | "name": null,
885 | "ofType": {
886 | "kind": "ENUM",
887 | "name": "__TypeKind",
888 | "ofType": null
889 | }
890 | }
891 | },
892 | {
893 | "args": [],
894 | "deprecationReason": null,
895 | "description": null,
896 | "isDeprecated": false,
897 | "name": "inputFields",
898 | "type": {
899 | "kind": "LIST",
900 | "name": null,
901 | "ofType": {
902 | "kind": "NON_NULL",
903 | "name": null,
904 | "ofType": {
905 | "kind": "OBJECT",
906 | "name": "__InputValue",
907 | "ofType": null
908 | }
909 | }
910 | }
911 | },
912 | {
913 | "args": [],
914 | "deprecationReason": null,
915 | "description": null,
916 | "isDeprecated": false,
917 | "name": "ofType",
918 | "type": {
919 | "kind": "OBJECT",
920 | "name": "__Type",
921 | "ofType": null
922 | }
923 | },
924 | {
925 | "args": [],
926 | "deprecationReason": null,
927 | "description": null,
928 | "isDeprecated": false,
929 | "name": "name",
930 | "type": {
931 | "kind": "SCALAR",
932 | "name": "String",
933 | "ofType": null
934 | }
935 | },
936 | {
937 | "args": [],
938 | "deprecationReason": null,
939 | "description": null,
940 | "isDeprecated": false,
941 | "name": "possibleTypes",
942 | "type": {
943 | "kind": "LIST",
944 | "name": null,
945 | "ofType": {
946 | "kind": "NON_NULL",
947 | "name": null,
948 | "ofType": {
949 | "kind": "OBJECT",
950 | "name": "__Type",
951 | "ofType": null
952 | }
953 | }
954 | }
955 | }
956 | ],
957 | "inputFields": null,
958 | "interfaces": [],
959 | "kind": "OBJECT",
960 | "name": "__Type",
961 | "possibleTypes": null
962 | },
963 | {
964 | "description": null,
965 | "enumValues": null,
966 | "fields": [
967 | {
968 | "args": [
969 | {
970 | "defaultValue": null,
971 | "description": "The ID of an object",
972 | "name": "id",
973 | "type": {
974 | "kind": "NON_NULL",
975 | "name": null,
976 | "ofType": {
977 | "kind": "SCALAR",
978 | "name": "ID",
979 | "ofType": null
980 | }
981 | }
982 | }
983 | ],
984 | "deprecationReason": null,
985 | "description": "Fetches an object given its ID",
986 | "isDeprecated": false,
987 | "name": "node",
988 | "type": {
989 | "kind": "INTERFACE",
990 | "name": "Node",
991 | "ofType": null
992 | }
993 | },
994 | {
995 | "args": [],
996 | "deprecationReason": null,
997 | "description": null,
998 | "isDeprecated": false,
999 | "name": "viewer",
1000 | "type": {
1001 | "kind": "OBJECT",
1002 | "name": "User",
1003 | "ofType": null
1004 | }
1005 | }
1006 | ],
1007 | "inputFields": null,
1008 | "interfaces": [],
1009 | "kind": "OBJECT",
1010 | "name": "Query",
1011 | "possibleTypes": null
1012 | },
1013 | {
1014 | "description": "A shiny widget'",
1015 | "enumValues": null,
1016 | "fields": [
1017 | {
1018 | "args": [],
1019 | "deprecationReason": null,
1020 | "description": "The ID of an object",
1021 | "isDeprecated": false,
1022 | "name": "id",
1023 | "type": {
1024 | "kind": "NON_NULL",
1025 | "name": null,
1026 | "ofType": {
1027 | "kind": "SCALAR",
1028 | "name": "ID",
1029 | "ofType": null
1030 | }
1031 | }
1032 | },
1033 | {
1034 | "args": [],
1035 | "deprecationReason": null,
1036 | "description": "The name of the widget",
1037 | "isDeprecated": false,
1038 | "name": "name",
1039 | "type": {
1040 | "kind": "SCALAR",
1041 | "name": "String",
1042 | "ofType": null
1043 | }
1044 | }
1045 | ],
1046 | "inputFields": null,
1047 | "interfaces": [
1048 | {
1049 | "kind": "INTERFACE",
1050 | "name": "Node",
1051 | "ofType": null
1052 | }
1053 | ],
1054 | "kind": "OBJECT",
1055 | "name": "Widget",
1056 | "possibleTypes": null
1057 | },
1058 | {
1059 | "description": "A person who uses our app",
1060 | "enumValues": null,
1061 | "fields": [
1062 | {
1063 | "args": [],
1064 | "deprecationReason": null,
1065 | "description": "The ID of an object",
1066 | "isDeprecated": false,
1067 | "name": "id",
1068 | "type": {
1069 | "kind": "NON_NULL",
1070 | "name": null,
1071 | "ofType": {
1072 | "kind": "SCALAR",
1073 | "name": "ID",
1074 | "ofType": null
1075 | }
1076 | }
1077 | },
1078 | {
1079 | "args": [
1080 | {
1081 | "defaultValue": null,
1082 | "description": null,
1083 | "name": "last",
1084 | "type": {
1085 | "kind": "SCALAR",
1086 | "name": "Int",
1087 | "ofType": null
1088 | }
1089 | },
1090 | {
1091 | "defaultValue": null,
1092 | "description": null,
1093 | "name": "before",
1094 | "type": {
1095 | "kind": "SCALAR",
1096 | "name": "String",
1097 | "ofType": null
1098 | }
1099 | },
1100 | {
1101 | "defaultValue": null,
1102 | "description": null,
1103 | "name": "after",
1104 | "type": {
1105 | "kind": "SCALAR",
1106 | "name": "String",
1107 | "ofType": null
1108 | }
1109 | },
1110 | {
1111 | "defaultValue": null,
1112 | "description": null,
1113 | "name": "first",
1114 | "type": {
1115 | "kind": "SCALAR",
1116 | "name": "Int",
1117 | "ofType": null
1118 | }
1119 | }
1120 | ],
1121 | "deprecationReason": null,
1122 | "description": "A person's collection of widgets",
1123 | "isDeprecated": false,
1124 | "name": "widgets",
1125 | "type": {
1126 | "kind": "OBJECT",
1127 | "name": "WidgetConnectionConnection",
1128 | "ofType": null
1129 | }
1130 | }
1131 | ],
1132 | "inputFields": null,
1133 | "interfaces": [
1134 | {
1135 | "kind": "INTERFACE",
1136 | "name": "Node",
1137 | "ofType": null
1138 | }
1139 | ],
1140 | "kind": "OBJECT",
1141 | "name": "User",
1142 | "possibleTypes": null
1143 | }
1144 | ]
1145 | }
1146 | }
1147 | }
--------------------------------------------------------------------------------