Ecto Changeset vs Absinthe Scalar Type Validation?

I can see some advantages for the custom scalar approach

  • you get documentation for the scalar types built in
  • your graphQL is the single source of truth for how inputs are structured/validated
  • Mutation responses only need to contain the record, without the need for a wrapper to return messages/status

However, I prefer to return validation errors as Data, not errors. Here’s a good blog post on the topic.

There are a several advantages:

  • Changeset validations are more powerful
  • Keeps all validation code in one place
  • Separates “Developer Errors” from “Validations”, so they can be handled differently.
  • Allows you to customize validation error messages
  • Easy to test
  • Decouples your GraphQL from your Database, as @NobbZ pointed out.

In practice, it’s not quite this simple.

You could, in theory, have a GraphQL mutation with no non_null fields, and string inputs, and then handle all validations - including required checks and casting to the appropriate types - in Ecto. But then you’re removing all of the introspection that is so useful. Expressing which fields are required and what types they are is important information for people developing your app. With GraphQL, documentation of field types is coupled to validation of field types - you really can’t have one without the other. So for simple types and required validations, I don’t obscure this information.

2 Likes