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

feat: Add validation queries (WIP) #294

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

sezaru
Copy link
Contributor

@sezaru sezaru commented Mar 27, 2025

This is a first version of having validation queries for mutations. The idea is to have an API that will work similarly to what AshPhoenix.Form.validate does, in other words, instead of having to duplicate validation logic in the frontend, the frontend can call the validation query and get the data directly from the backend.

Right now there are some issues with this PR:

  1. The validation queries are generated as mutations but they don't mutate anything, so maybe we should change them to be queries?
    One possible argument against this is that this would make using the validation api harder for the frontend developer since they would need to have a specific query for a the validation query and one for the mutation, while if both are mutations, then the only change is the function name.

Also, another thing to think about is that maybe we could instead of generating a new graphql api only to validate, we could add a validate input to the mutation itself and then the frontend keeps using the same API for both cases, just changing the validate boolean to define when validate and when submit (honestly, now that I think about it, I think this would be probably the best solution both in our side and also for implementing in the frontend).

  1. I implemented it for create and update actions, I didn't do it for generic actions, maybe we should have that too?

  2. I'm not sure if I should add support for all the other options that create and update actions have in their schema to the validation actions.

  3. I didn't add any unit tests for now since this has a great chance to change.

Here is a resource that I used to test it out:

defmodule ValidateGraphql.Domain.Resource do
  @moduledoc false

  use Ash.Resource,
      domain: ValidateGraphql.Domain,
      data_layer: AshPostgres.DataLayer,
      extensions: [AshGraphql.Resource]

  attributes do
    uuid_primary_key :id

    attribute :first_attr, :string, public?: true
    attribute :second_attr, :string, public?: true, allow_nil?: false
  end

  graphql do
    type :resource

    mutations do
      create :create, :create
      validate :validate_create, :create

      update :update, :update
      validate :validate_update, :update
    end
  end

  postgres do
    table "resource"

    repo ValidateGraphql.Repo
  end

  identities do
    identity :unique_second_attr, [:second_attr]
  end

  actions do
    defaults [:read, :destroy]

    create :create do
      accept [:first_attr, :second_attr]

      argument :first_arg, :string
      argument :second_arg, :string, allow_nil?: false
    end

    update :update do
      accept [:first_attr, :second_attr]

      argument :first_arg, :string
      argument :second_arg, :string, allow_nil?: false
    end
  end
end

Contributor checklist

  • Features include unit/acceptance tests (it doesn't for now)

@sezaru
Copy link
Contributor Author

sezaru commented Mar 28, 2025

Now that I think about it, ignore the part about adding the validate option to the mutation directly, even though I believe that would be the best approach for ease of use, it would not work since the validate version of the mutation needs to not have any field as required.

@zachdaniel
Copy link
Contributor

👋 just want to let you know this is still on my list. I've been mega busy the past week or so. I hope to get to it this week but it may be next week before I have the chance.

@sezaru
Copy link
Contributor Author

sezaru commented Apr 3, 2025

Don't worry, take your time!

@zachdaniel
Copy link
Contributor

So your idea of making validate an option to mutations is actually really interesting. I don't think we can do it for default queries because they don't return a "result object", but theoretically if there is an input called something like onlyValidate: true, then we don't need any fancy new type generation or anything! We can just return an empty list of errors. We have to keep in mind that validating will just do the "cheap" validations not necessarily everything so you can of course still get errors back, but I think that idea is a winner and I'd like to see that explored. Would you be willing to spike out that work?

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