Is your feature request related to a problem? Please describe.
Errors in the schema definition can be hard to spot. When defining a directive that does not exist, the error is silently swallowed, same with non-existing arguments.
We could shorten the feedback loop by doing a formal validation of the schema.
Describe the solution you'd like
The GraphQL specification allows formal definition of server-side directives. https://facebook.github.io/graphql/June2018/#sec-Type-System.Directives
In the spirit of schema-first, i think we should base our validation on SDL definitions.
For example, the @paginate directive would be formally specified as:
directive @paginate(
type: PAGINATOR_TYPE = PAGINATOR
builder: String
model: String
) on FIELD_DEFINITION
enum PAGINATOR_TYPE {
PAGINATOR @enum(value: "paginator")
CONNECTION @enum(value: "connection")
}
Such a definition would play a nice double-role: It would serve as self-documenting validation for the schema definition.
@spawnia Really like this idea.. just to clarify, would this add the @paginate directive to the introspection or, since it's not intended for the client side, would it just be removed from introspection while still being used for validation?
Those definitions will sit on the Directive classes and are gathered during the Directive registration. After schema parsing, the resulting AST can be validated against them. Validation would run exactly once, after which the schema is cached.
The client schema is not affected, since the directive definitions are not actually part of the final, executable schema.
I defined the directive definitions just for IDE auto-completion…
Does the webonyx/graphql-php support this??
So, this intend to solve #345 ?
@robsontenorio No. This is about validation for writing the schema itself, #345 is about validation for the queries sent by a client.
@yaquawa If you can share your directive definitions here, that would be great. @jbbr has prepared some as well.
We will still have to figure out the best way of including them and utilizing them, but having them defined here will be a great starting point. :)
I've created a schema file for the lighthouse server-schema "on the go". So it's incomplete/WIP.
But it might be a good starting point for either automatic generation of such a file or getting IDE-autocompletion right now.
This schema brings lighthouse autocompletion to Intellij/PHPStorm with the current alpha release (2.0.0-alpha.3) of the graphql intellij plugin. See https://github.com/jimkyndemeyer/js-graphql-intellij-plugin/releases/tag/2.0.0-alpha-3 for an installation guide
Expand
_directives.graphql
# Scalar directives
directive @scalar(class: String!) on SCALAR
# ENUM directives
directive @enum(value: ID!) on ENUM_VALUE
# Union directives
directive @union(resolver: String!) on UNION
# Interface directives
directive @interface(resolver: String!) on INTERFACE
# Object directives
directive @group(middleware: [String!]!) on OBJECT
directive @security(depth: Int!, complexity: Int!) on OBJECT
# Field directives
directive @field(resolver: String!) on FIELD_DEFINITION
directive @rename(attribute: String!) on FIELD_DEFINITION
directive @find(model: String!) on FIELD_DEFINITION
directive @paginate(type: String, model: String, scopes: [String]) on FIELD_DEFINITION
directive @all(relation: String, model: String, scopes: [String]) on FIELD_DEFINITION
directive @rules(apply: [String!]!) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION
directive @validate(validator: String, rules: [String]) on ARGUMENT_DEFINITION | FIELD_DEFINITION | INPUT_FIELD_DEFINITION
directive @create(model: String!, flatten: Boolean) on FIELD_DEFINITION
directive @update(model: String!, flatten: Boolean) on FIELD_DEFINITION
directive @delete(model: String!, flatten: Boolean) on FIELD_DEFINITION
directive @hasMany(type: String, relation: String, model: String, scopes: [String]) on FIELD_DEFINITION
directive @belongsTo(relation: String) on FIELD_DEFINITION
directive @hasOne(relation: String) on FIELD_DEFINITION
directive @lazyLoad(relations: [String!]!) on FIELD_DEFINITION
directive @middleware(checks: [String!]!) on FIELD_DEFINITION
directive @cache(private: Boolean, maxAge: Int) on FIELD_DEFINITION
# Argument directives
directive @eq(key: String) on ARGUMENT_DEFINITION
directive @neq(key: String) on ARGUMENT_DEFINITION
directive @in(key: String) on ARGUMENT_DEFINITION
directive @where(operator: String!, clause: String, key: String) on ARGUMENT_DEFINITION
@spawnia Thanks @jbbr for sharing the directive declarations, this is what I did too.
Here is some pseudo-code i have written up a while ago that might be a step towards
a structured way of validating server-side directives.
/**
* @return string
*/
public static function description(): string
{
return '';
}
public static function typeSystemDefinition(): string
{
return
(self::description() ? self::description() . PHP_EOL : '')
. 'directive ' . self::name() . ' on ' . PHP_EOL
. self::directiveLocations() . PHP_EOL;
}
protected static function directiveLocations()
{
return collect(class_implements(static::class))
->map(function (string $interfaceFQN) {
return class_basename($interfaceFQN);
})
->map(function (string $interfaceName) {
switch ($interfaceName) {
case 'SchemaDirective':
return 'SCHEMA';
case 'ScalarDirective':
return 'SCALAR';
// TODO add all types from http://facebook.github.io/graphql/June2018/#sec-Type-System.Directives
default:
return null;
}
})
// Interfaces that do not correspond to a location are null and removed here
->filter()
->reduce(function (string $definitions, string $directiveLocation) {
return $definitions . '| ' . $directiveLocation . PHP_EOL;
});
}
Just tried out the latest version of https://github.com/jimkyndemeyer/js-graphql-intellij-plugin/releases
It is working really well. This is a really valuable feature to have, would love it if
somebody could try hands on an automatic generation of directives SDL.
As a stopgap for anyone else who wants it, I made a gist of all the definitions from the documentation, including a few corrections.
https://gist.github.com/hipsterjazzbo/0693e88eab814fb32314667a7a8c8e63
@hipsterjazzbo how about you contribute the fixes back?
@jbbr or @spawnia, would one of you be willing to please explain how the directives folks are providing were made to be recognized by PhpStorm? I'm not sure where to put the _directives.graphql file or the definitions that @hipsterjazzbo provided. This is probably very basic, but I'm likely not the only one that isn't sure how to apply what folks are discussing here within the context of PhpStorm. Thank you!
I put it in graphql/directives.graphql, PHPStorm is picking it up just fine.
As a stopgap for anyone else who wants it, I made a gist of all the definitions from the documentation, including a few corrections.
https://gist.github.com/hipsterjazzbo/0693e88eab814fb32314667a7a8c8e63
updated the gist, it was missing @bcrypt @cacheKey @globalId and for @whereBetween changed the definition to new syntax
https://gist.github.com/akkhan20/9f534d409617fe584a2b436cdced0480
Some of definitions from official page show errors:


what is wrong with it?
Those directives are structured in a way that makes it impossible to correctly express in SDL.
@enum takes any SDL literal as a value. There is no type to express that.
RulesMessageMap is a map with variable keys. Again, there is no way to express that in the GraphQL type system.
I've created a schema file for the lighthouse server-schema "on the go". So it's incomplete/WIP.
But it might be a good starting point for either automatic generation of such a file or getting IDE-autocompletion right now.This schema brings lighthouse autocompletion to Intellij/PHPStorm with the current alpha release (
2.0.0-alpha.3) of the graphql intellij plugin. See https://github.com/jimkyndemeyer/js-graphql-intellij-plugin/releases/tag/2.0.0-alpha-3 for an installation guide
Expand_directives.graphql
I'm following the tutorial for the current master version (4.1),
https://lighthouse-php.com/4.1/getting-started/tutorial.html#installation
I have installed the JS GraphQL IntelliJ Plugin, but all the directives where still marked as undefined, thus I took the directives listed in your post and pasted them at the beginning of my shema.graphql file, everything did seem to work but one, the @find directive as you can see from the image

How to fix this?
Edit: it was a problem with the Post Model.
Hey! I'm sorry to reopen the discussion of issue, but despite the php artisan lighthouse:ide-helper I can't seem to get this to work. The schema always says unknown directive, and the schema-directives.graphql file generated contains errors. Do you have any tips on how to solve this? I'm using the JS GraphQL intellij plugin as suggested during installation
@truesteps see https://github.com/nuwave/lighthouse/issues/1661#issuecomment-759715155
@spawnia thanks, also is there a way to make the editor recognize the schema-directives.graphql file if it's outside of the graphql folder? My editor doesn't seem to register it, only if its directives.graphql in the graphql folder
The current location works for me 🤷
For me it only registers it if it's in a file called directives.graphql and in the graphql folder... Oh well at least I can copy the autogenerated file there
Most helpful comment
As a stopgap for anyone else who wants it, I made a gist of all the definitions from the documentation, including a few corrections.
https://gist.github.com/hipsterjazzbo/0693e88eab814fb32314667a7a8c8e63