How to create custom AshJsonApi to get a user by two parameter

How do create custom api to get a user by their :first_name and :date_of_birth?

read :get_user do
  argument :first_name, :string do
    allow_nil? false
  end

  argument :date_of_birth, :date do
    allow_nil? false
  end
end

There isn’t much information in your post so I’m assuming you have setup the AshJsonAPI as described here: Getting started with AshJsonApi — ash_json_api v1.0.0 . With that assumption, I’m guessing this is what you need on the User resource to get you the API you need.

defmodule Hello.User do
  use Ash.Resource,
    data_layer: AshPostgres.DataLayer,
    domain: Hello.Users,
    extensions: [AshJsonApi.Resource]

  postgres do
    table "users"
    repo Hello.Repo
  end

  attributes do
    uuid_primary_key :id

    attribute :first_name, :string, public?: true
    attribute :date_of_birth, :date, public?: true
    .... other attributes
  end

  json_api do
    type "user"

    routes do
      base "/users"

      get :get_user, route: "/find"
    end
  end

  actions do
    read :get_user do
      argument :first_name, :string do
        allow_nil? false
      end

      argument :date_of_birth, :date do
        allow_nil? false
      end

      filter expr(first_name == ^arg(:first_name) && date_of_birth == ^arg(:date_of_birth))
    end
  end

end

Basically, you are missing the filter macro in your read action. In the get route, the first argument :get_user is the read action name defined inside actions and the route option is given to make url as GET /users/find, otherwise the default route for a get path will result in /users/:id where :id is a placeholder and is not relevant in your case.

The API will return all the fields marked as public?: true in the attributes section.

1 Like
filter expr(first_name == ^arg(:first_name) && date_of_birth == ^arg(:date_of_birth))

** (RuntimeError) Cannot use `&&` without adding the extension `ash-functions` to your repo.

I already tried filter macro, but I got an issue with invalid_filter_value:

filter expr(first_name == ^arg(:first_name) and date_of_birth == ^arg(:date_of_birth))
{
    "errors": [
        {
            "code": "invalid_filter_value",
            "id": "26d912d6-c9d0-4a42-a00a-3683d236df07",
            "status": "400",
            "title": "invalid_filter_value",
            "detail": "Invalid filter value `\"user\"`"
        }
    ],
    "jsonapi": {
        "version": "1.0"
    }
}

In my Repo module, I have the following:

defmodule Hello.Repo do
  use AshPostgres.Repo,
    otp_app: :hello

  # Installs Postgres extensions that ash commonly uses
  def installed_extensions do
    ["ash-functions"]
  end
end

Are you using Ash 3 or 2? I think this got added recently in Ash 3. Official instructions are here: Ash Framework

2 Likes

"Raised error: 014f3a37-22d5-4875-8014-2767c1dd5417\n\n** (Ash.Error.Query.InvalidFilterValue) Invalid filter value

Your uuid has new lines at the end, it’s not a valid uuid

Thank you so much.