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

Add directive support #225

Merged
merged 7 commits into from
Feb 22, 2020

Conversation

paulpdaniels
Copy link
Collaborator

Revamped version of #192

This adds schema directives which are needed for such extensions as cache-control and federation. In order to test the behavior I also included an implementation of the cache-control extension using directives and the new wrappers.

case InputValue.ObjectValue(fields) =>
fields.map { case (key, value) => s"$key: ${renderDirectiveArgument(value)}" }.mkString("{", ",", "}")
case InputValue.VariableValue(_) =>
throw new Exception("Variable values are not allowed in a directive declaration")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather not render it here than throwing an exception.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking the spec after you mentioned this I realized there are a couple more things to be mindful of: https://spec.graphql.org/June2018/#sec-Type-System.Directives

Validation

A directive definition must not contain the use of a directive which references itself directly.
A directive definition must not contain the use of a directive which references itself indirectly by referencing a Type or Directive which transitively includes a reference to this directive.
The directive must not have a name which begins with the characters __ (two underscores).
For each argument of the directive:
The argument must not have a name which begins with the characters __ (two underscores).
The argument must accept a type where IsInputType(argumentType) returns true.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if it would be possible to resolve these at compile time, so it probably would have to be a runtime error, but the question is how should we handle it? Agree that throwing isn't the best option, should we have two rendering methods? one that simply suppresses errors and one that returns an IO[ValidationError, String]

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit similar to issue #170 where we lack a way to report something abnormal within the schema. Ideally we should fail at the point of building the schema rather than later during query execution or rendering like here.

It bothers me to make graphQL(...) return an effect because attaching the wrappers with @@ wouldn't be as smooth as it is now, but how about making .interpreter return an effect? That way we can build the schema easily, but when we turn it into an interpreter (which we do only once), we verify that the schema is valid and fail if it's not. What do you think?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw if we go for that solution, we can do it in a later PR and just remove the check for now (so that you don't need to implement the whole thing to get this PR merged).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.interpreter return an effect

I think this makes sense, since it is the "effect" of becoming an interpretable schema.

Ok I'm fixing so that it will just remove the arguments if they aren't valid and then we can fix it with the change you mentioned above.

core/src/test/scala/caliban/RenderingSpec.scala Outdated Show resolved Hide resolved
core/src/main/scala/caliban/wrappers/ApolloCaching.scala Outdated Show resolved Hide resolved
@ghostdogpr
Copy link
Owner

ghostdogpr commented Feb 21, 2020

This is really nice!

Additionally can you mention in the docs:

  • in Schema there's the list of annotations supported, you can add the new one
  • in Middleware there's the list of builtin wrappers, you can add Apollo Caching alongside Apollo Tracing

Copy link
Owner

@ghostdogpr ghostdogpr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just 2 tiny remarks and we’re good to ship!

core/src/test/scala/caliban/TestUtils.scala Show resolved Hide resolved
vuepress/docs/docs/middleware.md Outdated Show resolved Hide resolved
@ghostdogpr ghostdogpr merged commit b347121 into ghostdogpr:master Feb 22, 2020
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

Successfully merging this pull request may close these issues.

2 participants