AstSimpleFilter

When start working with Absinthe, I want to add the ability to filter a given model by any fields using eq, lt, gt, in,...

So I created this package, it does 2 things:

  1. Allow to add filters and pagination parameters to GraphQL query.

  2. Allow to filter a model using the above filters parameter

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/ast_simple_filter.

Installation

If available in Hex, the package can be installed by adding ast_simple_filter to your list of dependencies in mix.exs:

def deps do
  [
    {:ast_simple_filter, "~> 0.0.1"}
  ]
end

Usage

Add filter

Define some common types (Optional):

use AstSimpleFilter.DefineCommonObjects

This will define:

:asf_datetime scalar to use for datetime fields.

:asf_date scalar to use for date fields.

:asf_pagination_info object, which contains total entries, page_number and per_page.

:ast_pagination_input input, which allows to specify page_number and per_page.

Define output (Optional)

use AstSimpleFilter.DefineTypes, base_name: :<base_name>, field_types: <field_types_list>, custom_datetime_type: :<custom_datetime_type>, :custom_date_type: :<custom_date_type>, custom_meta_type: :<custom_meta_type>

Example of a <field_types_list> is: [{id: :id}, {age: :integer}, {email: :string}]. We can replace field_types: [...] by kclass: <Model>, in this case, it will include all fields of <Model> into <base_name>_custom_fields, If we omit custom_datetime_type: :<custom_datetime_type>, :custom_date_type: <custom_date_type>, custom_meta_type: <custom_meta_type>, then we need to define common types first (Step above).

This will define 2 objects:

:<base_name>_custom_fields

  object :<base_name>_results do
    field :data, list_of(:<base_name>_custom_fields)
    field :meta, :asf_pagination_info (or :custom_meta_type)
  end

Define filter input

use AstSimpleFilter.DefineFilterInput, base_name: :<base_name>, field_types: <field_types_list>

Example of a <field_types_list> is: [{id: :id}, {age: :integer}, {email: :string}]. Again, we can replace field_types: [...] by kclass: <Model>

This will define an input like this:

  input_object user_filter_input do
    field age_eq :integer
    field age_neq :integer
    field age_lt :integer
    field age_lte :integer
    field age_gt :integer
    field age_gte :integer
    field age_in list_of(:integer)
    field age_nin list_of(:integer)
    field age_nil :boolean
  end

Then we can define query like this

  query do
    @desc "Get a list of users"
    field :users, :user_results do
      arg(:filters, :user_filter_input)
      arg(:pagination, :asf_pagination_input)
      resolve fn _parent, args, resolution ->
        ...
      end
    end
  end

Add asf_filter function

In <model> add:

import Ecto.Query
use AstSimpleFilter.DefineFilterFunctions, <Model>

This will define asf_filter(%{}) function, which accept the arg.filters to filter <Model> Note that because the asf_filter use Ecto.Query, so we need to import it first.

Example

https://github.com/tranngocsam/absinthe-simple-filter