gqlgen icon indicating copy to clipboard operation
gqlgen copied to clipboard

Is is possible to get field directives in mutation hook?

Open acelot opened this issue 4 years ago • 7 comments

What happened?

According to https://gqlgen.com/recipes/modelgen-hook/ we can mutate generated models file.

What did you expect?

I want to add some tags into struct fields depending on existing directives.

Minimal graphql.schema and models to reproduce

directive @testDirective(value: Int!) on INPUT_FIELD_DEFINITION

input SomeInput {
  someField: Int! @testDirective(value: 100)
}

Expected struct:

type SomeInput struct {
	SomeField int `json:"someField" test:"100"`
}

versions

  • gqlgen version? 0.12.2
  • go version? 1.15
  • dep or go modules? go.mod

acelot avatar Sep 29 '20 11:09 acelot

@acelot did you find a way?

And second question: if you use the code from https://gqlgen.com/recipes/modelgen-hook/ is the generator generating resolvers files?

frederikhors avatar Dec 17 '20 13:12 frederikhors

@frederikhors I originally wanted to implement a validation feature via model attributes. But then I decided not to do that and made a validation through directives resolvers.

About the second question - no, the generator only generates models.

acelot avatar Dec 17 '20 16:12 acelot

Interesting I'm here for the same need: validation!

validation through directives resolvers

Can I ask you for a gist? What do you mean with this?

frederikhors avatar Dec 17 '20 17:12 frederikhors

I cannot provide the code, but I can explain it in general terms. I used an example from the documentation and wrote directives for each type that needs to be validated. For example:

directive @validateString(minLength: Int!, maxLength: Int!, trim: Boolean!) on INPUT_FIELD_DEFINITION
directive @validateInt(minValue: Int!, maxValue: Int!) on INPUT_FIELD_DEFINITION

Then I wrote resolvers for these directives so that they validate the input field values using their arguments and inject the result in the context. I made it so that the validators themselves do not reject the request and do not return a response, but put their results into the context. Further, the field resolvers (regular resolvers, not directives) themselves take these results from context and decide what to do next.

acelot avatar Dec 18 '20 03:12 acelot

Oh wow. This is another way to see the problem. Thanks for your idea!

frederikhors avatar Dec 18 '20 13:12 frederikhors

@acelot Your approach is not bad but do not allow us to validate all fields and return errors for all fields at once. If error appear on one of the fields the other directives are not executed.

So about your initial question "Is is possible to get field directives in mutation hook" I think if we have answer on it it will help us to implement validator that will be more flexible

a-shumanski avatar Feb 24 '21 08:02 a-shumanski

I have created a PR #1650 which exposes directives to a FieldMutateHook for exactly this reason. this allows our validation logic to add go-playground/validator tags to our model based off a constraint directive similar to the constraint directive outlined in https://www.apollographql.com/blog/backend/validation/graphql-validation-using-directives/

tprebs avatar Oct 08 '21 14:10 tprebs