Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extending input types #641

Closed
tamlyn opened this issue Feb 19, 2018 · 8 comments
Closed

Extending input types #641

tamlyn opened this issue Feb 19, 2018 · 8 comments

Comments

@tamlyn
Copy link

tamlyn commented Feb 19, 2018

I'm finding that extend doesn't work as expected for input types.

// server.js
const express = require('express')
const { graphqlExpress, graphiqlExpress } = require('apollo-server-express')
const { makeExecutableSchema } = require('graphql-tools')
const bodyParser = require('body-parser')

const app = express()
const typeDefs = `
type Query {
  getFoo: Foo
}
type Foo {
  foo: String
}
extend type Foo {
  bar: String
}

type Mutation {
  updateFoo(input: FooInput): Foo
}
input FooInput {
  foo: String
}
extend input FooInput {
  bar: String
}
`

const resolvers = {
  Query: {
    getFoo: () => ({ foo: 'hey', bar: 'ho' }),
  },
  Mutation: {
    updateFoo: (_, { input }) => input,
  },
}

const schema = makeExecutableSchema({ typeDefs, resolvers })

app.use(bodyParser.json({ limit: '50mb' }))
app.use('/graphql', graphqlExpress({ schema }))
app.use('/graphiql', graphiqlExpress({ endpointURL: '/graphql' }))

app.listen(8080)
# start the server
$ node server.js

# try a query
$ curl -XPOST -d'{"query":"{getFoo{foo, bar}}"}' -H 'Content-type: application/json' http://localhost:8080/graphql
{"data":{"getFoo":{"foo":"hey","bar":"ho"}}}

# try a mutation
$ curl -XPOST -d '{"query":"mutation($input: FooInput){updateFoo(input: $input){foo, bar}}","variables":{"input":{"foo":"ey","bar":"oh"}}}' -H 'Content-type: application/json' http://localhost:8080/graphql
{"errors":[{"message":"Variable \"$input\" got invalid value {\"foo\":\"ey\",\"bar\":\"oh\"}; Field \"bar\" is not defined by type FooInput.","locations":[{"line":1,"column":10}]}]}

Is this a bug, a deliberate omission or just a feature that has not yet been implemented?

@kbrandwijk
Copy link
Contributor

@tamlyn See graphql/graphql-js#1095.

@tamlyn
Copy link
Author

tamlyn commented Feb 19, 2018

Thanks. Great to see it's on the agenda already. Once this is implemented in graphql-js will it automatically work here? If so I guess this can be closed.

@grenierdev
Copy link

@tamlyn I have a fork of graphql-js which implements enum & input extension (wip PR). graphql-tools does not just work with newly extended enum & input type.

Some changes are needed in graphql-tools to understand the new types.

@grenierdev
Copy link

I'm waiting on my PR to get merge with the graphql:master before finishing up my changes to graphql-tools. And there is some breaking changes to Enum as described in #761.

You can find my WIP fork here which add support for enum/union/input extension to graphql-tools

@stubailo
Copy link
Contributor

Yeah, we won't be able to put this in graphql-tools until it's in the GraphQL specification, since we don't want to accidentally fork the spec.

@stubailo
Copy link
Contributor

Oh whoooooops OK it's actually merged there.

Does it still not work in graphql-tools? What do we need to do?

@grenierdev
Copy link

@stubailo It got merged and it's part of v14.0.0-rc.1. As noted in the changelog :

extendSchema extended with spec-compliant SDL extensions (#1373) - source

This mean that graphql-js now support the spec extensions.

@jure
Copy link
Contributor

jure commented Sep 5, 2018

Anyone know why its mechanism is still different from extend type? For example, extending types works fine, end result is a type with keys foo and bar:

    const typeDefAry = [
      `
      type Query {
        foo: String
      }`,
      `
      extend type Query {
        bar: String
      }
    `,
    ];

    const jsSchema = makeExecutableSchema({
      typeDefs: typeDefAry,
      resolvers: {},
    });
    expect(jsSchema.getQueryType().name).to.equal('Query');
    expect(jsSchema.getQueryType().getFields()).to.have.all.keys('foo', 'bar');

With inputs, it's different:

    const typeDefAry = [
      `
      input Query {
        foo: String
      }`,
      `
      extend input Query {
        bar: String
      }
    `,
    ];

    const jsSchema = makeExecutableSchema({
      typeDefs: typeDefAry,
      resolvers: {},
    });
    expect(jsSchema.getQueryType().name).to.equal('Query');
    expect(jsSchema.getQueryType().getFields()).to.have.all.keys('foo', 'bar');

Only the key foo will be in there. (Sorry for the confusing naming, it was the quickest way to test what I've been experiencing in practice.)

Any ideas? If not, I'd be happy to go looking.

Update: Found why it's not working in #948

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants