Skip to content

ConstraintString type appeared in graphql schema on the client #2

Closed
@dbuduev

Description

@dbuduev

ConstraintString leaked through introspection. Is it by design?
This makes GraphiQL unhappy.

Error: Invalid or incomplete schema, unknown type: ConstraintString. Ensure that a full introspection query is used in order to build a client schema.

ConstraintString can be revealed by the following query:

query Introspection { 
  __schema {
    types {
      name
      inputFields {
        type {
          name
        }
      }
    }
  }
}

Activity

confuser

confuser commented on Jun 8, 2018

@confuser
Owner

No, certainly not by design. Possibly a bug within graphql-tools.

yvele

yvele commented on Jun 13, 2018

@yvele

I have the same problem, and I filled an issue within graphql-tools ardatan/graphql-tools#842

Edit: I'm having this issue when trying to make schema stitching on underlying schema having directive constraints

koresar

koresar commented on Jun 25, 2018

@koresar
Contributor

UPD: ignore the below. The directive stopped working. :)
UPD2: If you'd remove the two scalars below it will make the directive work, but will break client side retrospection. So, choose your destiny. :)


I found a workaround! Omg, took a while.

Add this to your .graphql schema file (if you have one though):

# Current implementation on graphql-import does not support directives declared outside of the scehma (in node.js code).
# We have to redeclare each directive and type for now.
directive @constraint(
    # String constraints
    minLength: Int
    maxLength: Int
    startsWith: String
    endsWith: String
    notContains: String
    pattern: String
    format: String

    # Number constraints
    min: Int
    max: Int
    exclusiveMin: Int
    exclusiveMax: Int
    multipleOf: Int
) on INPUT_FIELD_DEFINITION

scalar ConstraintString

scalar ConstraintNumber
koresar

koresar commented on Jun 25, 2018

@koresar
Contributor

@confuser hey James,

Quick question. In this article
https://dev-blog.apollodata.com/reusable-graphql-schema-directives-131fb3a177d1
they suggest to override field.resolver. See AuthDirective example.

Any reason you went by creating the new ConstraintString type class?

confuser

confuser commented on Jun 25, 2018

@confuser
Owner

@koresar The recommendation seemed to be using custom scalar types to achieve this, rather than overriding the resolver function https://www.apollographql.com/docs/graphql-tools/schema-directives.html#Enforcing-value-restrictions I'm certainly open to switching to a resolver function instead if it eases pains people are facing.

koresar

koresar commented on Jun 25, 2018

@koresar
Contributor

Frankly, I tried this:

class MyConstraintDirective extends SchemaDirectiveVisitor {
    static getDirectiveDeclaration(directiveName) {
        return new GraphQLDirective({
            name: directiveName,
            locations: [DirectiveLocation.INPUT_FIELD_DEFINITION]
        });
    }

    visitInputFieldDefinition(field) {
        field.resolve = async function() {
            throw new Error("not valid");
        };
    }
}

But for some reason the resolve is never hit. The visitInputFieldDefinition is executed for every field though.

So, not sure what to do frankly.

koresar

koresar commented on Jun 25, 2018

@koresar
Contributor

I debugged a little. TL;DR: The makeExecutableSchema does not replace the directive object in schema.

  • The graphql-import people tell you to "declare the @constraint scalar in .graphql file". It effectively creates a directive object in schema. Which is right thing to do IMO. My IDE stops complaining about "undeclared directive!".
  • The makeExecutableSchema accepts the schemaDirectives and applies the schema visitor to them. But it does not replace the previously declared directive generated by graphql-import.

Here is a screenshot. I made it in node.js debugger one step before exiting the makeExecutableSchema. Basically, that schema variable is what I get.
image

@confuser where should I rant about it next? In apollographql/graphql-tools ? :)

koresar

koresar commented on Jul 4, 2018

@koresar
Contributor

I solved the problem. The @constaint is fully working. What I did:

  • ditched the graphql-yoga and the graphql-import.

Turns out Prisma and Apollo packages are not fully compatible.

Now I'm using Apollo Stack v2 (currently RC). The documentation does not match the actual API yet, but I figured all out.

confuser

confuser commented on Jul 4, 2018

@confuser
Owner

@koresar Interesting, so the new apollo-server v2 solves the issue with schema stitching without any changes here? I presume it doesn't resolve the problem you mentioned earlier around overwriting the resolver function instead of using custom scalars?

koresar

koresar commented on Jul 5, 2018

@koresar
Contributor

Sorry, should have mentioned. There were actually a lot of changes.

I had to rewrite schema stitching.

  • Removed all the Prisma's #import statements, and
  • used Apollo's mergeSchema() JS function.

It did solve all the problems I had.

The high level solution: do not use Prisma and Apollo packages in the same project. They are often incompatible.

koresar

koresar commented on Jul 6, 2018

@koresar
Contributor

Ok. I was wrong. Again. No, I did not fix all the problems I have. Even Apollo Stack v2 didn't help.

Currently:

  • Either directive works, but introspection doesn't.
  • Or directive does not work, but introspection works.

If I follow the README.md instructions then I get this error in the GraphQL Playground console: Invalid or incomplete schema, unknown type: ConstraintString.

If I add scalar ConstraintString to my schema then the directive stops working.

I believe that official Apollo docs are wrong: https://www.apollographql.com/docs/apollo-server/v2/features/creating-directives.html#Enforcing-value-restrictions
This way of implementing it does not work.

31 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @gerwinbrunner@padenj@cmartin81@arvi@danwetherald

        Issue actions

          ConstraintString type appeared in graphql schema on the client · Issue #2 · confuser/graphql-constraint-directive