Skip to content
This repository has been archived by the owner on Jun 30, 2021. It is now read-only.

Composable filters as request params #440

Merged
merged 22 commits into from
Oct 1, 2018
Merged

Composable filters as request params #440

merged 22 commits into from
Oct 1, 2018

Conversation

unnawut
Copy link
Contributor

@unnawut unnawut commented Aug 28, 2018

Closes #334

Overview

This PR adds support for a more advanced filtering. Instead of just search_term and search_terms, it's able to filter by conditions like eq (equals), neq (not equals), lt (less than), gte (greater than), etc.

Changes

  • Add a new EWallet.Web.MatchAllParser to support filtering with all conditions
  • Add a new EWallet.Web.MatchAnyParser to support filtering with any conditions

Implementation Details

This PR took inspirations from various existing open-sourced libraries but decided to write from scratch as the libraries are either very feature-rich that we use a very small subset of the feature, or very simple that it could easily be built on our existing parsers.

Also note that "match_any" is limited to 5 unique associations. This is due to the fact that Ecto supports only positional reference on joins. Named joins is coming in Ecto 3.0 but the release date is not set. So, I did a workaround by mapping the join sequence and build the dynamic query by having a fixed number of bindings (fixed to 5).

Usage

Supported comparators: eq, neq, lt, lte, gt, gte, contains and starts_with.

For example, the attributes below will filter for confirmed transactions that came from or went to the user with username "alice".

POST /transaction.all
{
  "match_all": [
    {
      "field": "status",
      "comparator": "eq",
      "value": "confirmed"
    }
  ],
  "match_any": [
    {
      "field": "from_user.username",
      "comparator": "eq",
      "value": "alice"
    },
    {
      "field": "to_user.username",
      "comparator": "eq",
      "value": "alice"
    }
  ]
}

Impact

New optional attributes: match_all and match_any added to /transaction.all's request format. No DB changes.

@unnawut unnawut added this to the v1.1 milestone Aug 28, 2018
@unnawut unnawut self-assigned this Aug 28, 2018
@ghost ghost added the s2/wip 🚧 label Aug 28, 2018
@unnawut
Copy link
Contributor Author

unnawut commented Aug 28, 2018

Remaining:

  • Support field value type casting similar to {field, :uuid} in the existing SearchParser
  • Support nested field (e.g. filter transactions by from_account.name, etc.)
  • Support predicate e.g. match: all or match: any

unnawut and others added 2 commits August 31, 2018 13:52
# Conflicts:
#	apps/admin_api/lib/admin_api/v1/controllers/transaction_controller.ex
@unnawut
Copy link
Contributor Author

unnawut commented Sep 12, 2018

Example for multiple predicates:

POST /transaction.all
{
  "match_all": [
    {
      "field": "from_user.id",
      "comparator": "eq",
      "value": "alice_id"
    },
    {
      "field": "to_user.id",
      "comparator": "eq",
      "value": "bob_id"
    }
  ],
  "match_any": [
    {
      "field": "status",
      "comparator": "eq",
      "value": "confirmed"
    },
    {
      "field": "status",
      "comparator": "eq",
      "value": "approved"
    }
  ]
}

Edited: removed "filters" level

@unnawut unnawut added the kind/enhancement 🚀 New feature or request label Sep 26, 2018
@unnawut
Copy link
Contributor Author

unnawut commented Sep 26, 2018

@T-Dnzt Added starts_with, OpenAPI specs and markdown docs. Please review again.

@unnawut unnawut merged commit 0cf03c9 into master Oct 1, 2018
@ghost ghost removed the s3/review 👀 label Oct 1, 2018
@unnawut unnawut deleted the 334-filtering branch October 1, 2018 08:44
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
kind/enhancement 🚀 New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement advanced filtering for Admin API
2 participants