Operators in GraphQL?

They will never be a part of the spec… it’s not designed to actually query a certain database.

However, you can send up your own data that a resolver can parse and use to query the data.

For example i’m using this for a sidebar filter to add AND clauses to a Postgres query:

{
  things(filter: {age: {gt: 18}, name: {eq: "Jane"}}) {
    id, age, name
  }
}

As you may have noticed this looks a lot like Mongo syntax! Then my resolver can parse this out like this (sorry it’s not JS syntax but you can replace with a switch statement):

  def fetch_things(filter_params) do
    base_query = from i in Interest,
      where: i.is_complete == true

    query_with_filters =
      # buildup several WHERE AND clauses for each field in map
      Enum.reduce(filter_params, base_query, fn {field, selector}, acc ->
        case selector do
          %{eq: value} ->
            where(acc, [r], field(r, ^field) == ^value)
          %{lt: value} ->
            where(acc, [r], field(r, ^field) < ^value)
          %{gt: value} ->
            where(acc, [r], field(r, ^field) > ^value)
          %{} -> # this can match *any* map not just an empty one
            base_query
        end
      end)

    {:ok, Repo.all(query_with_filters)}
  end

if you’re using Mongo it’s a bit simpler as you can buildup an object literal and pass the final object to the colleciton selector… but you need to make sure you whitelist the selector for safety so a client can filter anything (could be dangerous for certain apps) but if you use the object syntax the GraphQL types will do that for you.

1 Like