apollo-server: Bug: It is impossible to implement input type validation directive without breaking Playground
How to reproduce:
- Follow your own example in the docs: https://www.apollographql.com/docs/apollo-server/v2/features/creating-directives.html#Enforcing-value-restrictions
Problem:
- Either directive works, but Playgound doesn’t. (If I follow the instructions then I get this error in the GraphQL Playground console:
Invalid or incomplete schema, unknown type: LengthAtMost64
.) - Or directive does not work, but introspection works. (If I add
scalar LengthAtMost64
to my schema then the directive stops working.)
I tried both Apollo Stack v1 and v2.
The GraphQL Playground points to this file: http://cdn.jsdelivr.net/npm/graphql-playground-react@1.7.1/build/static/node_modules/graphql/utilities/buildClientSchema.js Namely, this function:
function getNamedType(typeName) {
if (typeDefCache[typeName]) {
return typeDefCache[typeName];
}
var typeIntrospection = typeIntrospectionMap[typeName];
if (!typeIntrospection) {
throw new Error('Invalid or incomplete schema, unknown type: ' + typeName + '. Ensure ' + 'that a full introspection query is used in order to build a ' + 'client schema.');
}
var typeDef = buildType(typeIntrospection);
typeDefCache[typeName] = typeDef;
return typeDef;
}
I found this bug by trying to use the @constraint
directive.
I have no idea what to do.
Are there any other ways to implement input type validation directive?
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 16
- Comments: 16 (2 by maintainers)
Is there a chance that this is fixable in the foreseeable future?
I was able to dupe and wrote it up under the following: https://github.com/tdharris/apollo-graphql-constraint-directive
I think this is the same behavior seen here. It starts in a working state with the suggested workaround, and then it can be broken quite easily with details provided in the
README
. I may be off on this, but it seems like the issue here as far as I can tell for now.This is a problem I have in another project where I am using
prisma/graphql-yoga
and the directive resolvers have been skipped over as well. My issue with the workaround approach is that I usemerge-graphql-schemas
since I have layers of schema files and need to have it attempt to merge various duplicates - I have ran into some issues there withapollographql/graphql-tools
on that point that I may need to dig around a bit to find again.The only solution that comes to mind - use Apollo stuff v1. It was a masterpiece. The v2 have a number of flaws and inconveniences yet.
On Sat., 8 Sep. 2018, 03:43 Alexey, notifications@github.com wrote:
I have the same issue. When I use package
graphql-constraint-directive
and provide scalar and directive to typeDefs, constraint directive stops working and scalar validation is skipped. If I don’t provide scalar and directive to my typeDefs - constraint works fine but IntrospectionSchema query fails on a client and GraphiQL shows errors that scalar is not defined in the schema. In the official apollo-server 2 directive example scalar type also isn’t provided and this example doesn’t work fine on GraphiQL and Playground. Also, a name of the scalar type is dynamically calculated by maxLength. Have you come up with solutions?For security reasons the best solution would be to not leak
LengthAtMost64
to Playground (client introspection) side. TheLengthAtMost64
should stay internal to the server.That’s why
directiveResolvers
worked really well in the past. It did not create any types in my schema.We also got the exact same issue, coming from the documentation: https://www.apollographql.com/docs/graphql-tools/schema-directives/#enforcing-value-restrictions
The example above doesn’t add any
scalar XXX
to the schema, leading us to believe “this is supposed to work”.Edit: Found solution in https://github.com/confuser/graphql-constraint-directive/issues/2#issuecomment-487838340.
@evans, It’s not only breaks the Playground. It is also breaks custom scalars
in my case (“apollo-server-express”: “2.0.4”) enabling
schemaDirectives
leads to such errors:UPD: in my case the problem was in a way I used import: was:
import { SchemaDirectiveVisitor } from 'graphql-tools';
must be:import { SchemaDirectiveVisitor } from 'apollo-server-express';
A temporary workaround for Apollo Stack 2.0 was found by @FrankSandqvist in here: https://github.com/confuser/graphql-constraint-directive/issues/2#issuecomment-404399563
TL;DR: make schema from resolvers+directives+typedefs, then merge more scalar typedefs, and then use the final schema in ApolloServer:
Boom! Now both your directive and Playground are working!
WARNING! The above solution is a bit dirty.
path/to/scalars
schema. So you might end up with loads ofLengthAtMost64
andStringWithMaxLength50WithMinLength5ThatConformsToEMAIL
etc rubbish types in your schema.Does this bug affect only
DirectiveLocation.INPUT_FIELD_DEFINITION
or other directive locations too?