hasura / graphql-data-specification

A specification for Data APIs with GraphQL
https://hasura.github.io/graphql-data-specification/
18 stars 3 forks source link

Field constraints in GraphQL schemas #21

Open beepsoft opened 1 year ago

beepsoft commented 1 year ago

I really like the idea of GDS ... and even the current Hasura metadata model! 😃

One aspect of Hasura-generated GraphQL schemas that I find lacking is the absence of constraints on model fields. While I understand that this isn't natively supported by GraphQL schemas, it would be incredibly helpful for clients utilizing the GraphQL schema to be aware of these constraints. Examples of useful constraints include field requirements, numerical data ranges, or text data formats (such as email, URL, or regex-defined constraints).

In an ideal world, Hasura metadata or GDS could be used to define field constraints and generate GraphQL directives (such as @constraint) for the fields. Is there a plan to implement such a feature in GDS?

rahulagarwal13 commented 1 year ago

Hey @beepsoft, thank you for your question and comments. Yes, there are plans to support this and in fact we have an RFC open for it - https://github.com/tirumaraiselvan/graphql-engine/blob/input-validations-rfc/rfcs/input-validations.md. What do you think of this RFC (cc @tirumaraiselvan )? Even though it is for V2, we will plan to implement such validations in a similar manner (i.e. in the AuthZ framework) in V3 metadata as well. For more visibility, we are working on defining the GDS spec more concretely as of now. One of the enhancements include bringing in permissions within the model object.

beepsoft commented 1 year ago

Hi @rahulagarwal13, thanks for pointing to the RFC. This is a great addition to have easier input validation at server side. For this we currently need an action if the check is not enough, so this definitely will be a great feature.

My proposal is about how we can inform the client side about about these validation rules. For instance, when the validate_input.type is static and defines a regular expression, or a frequently used field type like email or URL, these rules could be transmitted within the GraphQL schema. This may be also be used with http rules, but I'm not sure about it: should clients be able to invoke these URL-s?

In my HasuraConf project, I address this issue by generating a JSON Schema for my data model, which contains these validation rules, in addition to the GraphQL schema generated by Hasura. However, this approach is only feasible because I also produce Hasura metadata from a "meta model" (JPA) that encompasses these validation rules (JPA validation annotations, in my case).

A better solution would involve incorporating the validation rules into the Hasura metadata (as proposed in the input validation RFC) and communicating them to clients, ideally as a part of the GraphQL schema (using a directive like @validation_rule). Alternatively, generating a separate JSON Schema could also be a viable option.

olmohake commented 1 year ago

I am quite hyped about the gds as it addresses most of the things we were trying to solve by building an abstract data model on top of hasura for quite a while. Decoupling the database from the model enables a lot of things that would be nice to have. One feature i would love to see with 3.0 are scalar validations! It would be extremely helpful to be able to declare validations for a scalar once and have them applied globally for all columns and action inputs using it.

scalars:
  email:
     validations:
            http: uri-to-validator
            regex: 
                pattern: /.../
                message: "Not a valid E-Mail"

Publishing validation rules to client via schema introspection as an graphql extension would be super helpful for client side form validation and error messages. Alternatively hasura could return errors for all failed validations including the path within the model, so they can be displayed in the ui. This would increase dx quite a lot as we currently have to implement validations in the backend and ui separately to give the user a meaningful feed back.

Additionally this would also open a path towards i18n error messages, which aren't as urgently needed but would be extremely nice to have in the future.