question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Better validation and transformation of graphql input values

See original GitHub issue

Hi guys,

I have spent some time looking for a solution on how to implement data validation in graphql using directives. The idea seems very nice and clear: schema directives define validation rules to be applied to the data, eg

input ConsumerData {
  name: String @length(min: 1, max: 20)
}

However current approach described in the documentation refers to output types of directives only and suggests usage of Consumer<GraphQLFieldDefinition.Builder> together with GraphQLFieldDefinition.dataFetcher.

Applying the same approach to GraphQLInputObjectField wouldn’t work since GraphQLInputObjectField doesn’t have any kind of data transformer.

Would it make sense to add something like

interface DataTransformer<T> {
    public T transform(T value)
}

to GraphQLInputObjectField for the purpose of usage of directives? This could be used in ValuesResolver.coerceValueAstForInputObject.

To supply a DataTransformer to ValuesResolver one could use the same wiring approach as one currently used to update dataFetcher on GraphQLFieldDefinition.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:5
  • Comments:11 (7 by maintainers)

github_iconTop GitHub Comments

3reactions
bbakermancommented, Nov 4, 2018

One good question is where to put the code for input validation. If we copied the previous pattern we would attach it to each field of the Input object like we do on GraphqlFieldDefinitions.

But this is insufficient. For example a field like mutation { someObject(String input) has only a scalar type so putting code on the input object itself is no good.

Looking at the examples above we have

  • validation associated with a specific query / mutation field
  • validiation associated with specific input object fields regardless of query field
  • validation potentially associated with the input object itself (for all its fields say)

So it seems we need a registry that can take a named “node” and associate a validation bit of code with it. Those nodes could be “query fields (and hence their arguments)” , “input object fields” or “input objects” as a whole.

This starts to beg the question of having a SchemaExecutionRegistry that contains validation (by field/type name) and potentially later the “data fetchers” we have today again associated by field name.

This SchemaExecutionRegistry is probably a peer top the GraphqlSchema or at least a top level object inside the schema (since today you get the schema to get data fetchers).

1reaction
bbakermancommented, Aug 17, 2019

I have thought long and hard on this and tried to design new “SPI” to allow validation of input values.

However after much thought and code tribulation I have come to the position of adding now SPI but in fact doing what you describe

That is the validation is a precursor to DataFetching and that DataFetcher “enhancement” is the way to achieve it.

I have come to beleive this is the right approach because validationof the data to be executed needs to happen when all the query is valid ready to be executed.

The inputs to “input data validation” need to be perfectly “query valid” in GQK terms before you run actual business values validation. I have come to beleive that confusing “GQL query validation” eg structure of the text and inputs is not the same as validation of the input data.

To that end I have a POC in my personal repo

https://github.com/bbakerman/graphql-java-extended-validation

Its exactly what you describe.

I have tried to make it extensible via plugin validation rules. Whether it can truly do that easily requires some like you to help shape it out.

I have started also on a Java EL implementation where you put in Java EL rules in directives and have them run eg '${args.containsOneOf('a','b')}'

This is a side project of side project at the moment. I would love to collaborate with others to help shape this out into a published library and likely under the graphql-java project eventually.

@zyxist or anyone else on this thread interested in helping?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Argument and Input validation - TypeGraphQL
The standard way to ensure that inputs and arguments are correct, such as an email field that really contains a proper e-mail address,...
Read more >
GraphQL validation using directives
Out of the box, GraphQL supports validating your inputs based on type information. For example, you can ensure that an argument is a ......
Read more >
GraphQL: Transform input field to pass validation (trim string ...
I'm using a class-validator package to validate a link in the GraphQL input type. The problem is ...
Read more >
Queries and Mutations - GraphQL
On this page, you'll learn in detail about how to query a GraphQL server. Fields#. At its simplest, GraphQL is about asking for...
Read more >
API (GraphQL) - Overview - AWS Amplify Docs
The GraphQL Transform simplifies the process of developing, deploying, and maintaining GraphQL APIs. With it, you define your API using the GraphQL Schema ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found