digitallyinduced/thin-backend

allow filtering queries

jeyj0 opened this issue · 3 comments

jeyj0 commented

There's nothing beyond SELECT a, b, c FROM table; + joins yet

I've added docs on this here 3d3f06f Can you check this out?

jeyj0 commented

So we have:

  • SELECT a, b, c FROM table; + joins
  • SELECT a, b, c FROM table WHERE id = ?; + joins

This issue is about:

  • SELECT a, b, c FROM table WHERE ?

I think we can take prisma as inspiration for what complex queries could look like, as they already have everything required in their typescript API, and use objects (which map nicely to graphql) for a lot of it.

I'm imagining this for example:

{
  users(where: {
    email: {
      contains: "@gmail.com"
    },
    OR: [
      {
        organization: {
          plan: {
            id: { equals: "123456" }
          }
        }
      },
      {
        team: { plan: {
          id: { equals: "123456" }
        } }
      }
    ]
  }) {
    id
    email
  }
}

For which there could be a lot of syntactic sugar / shortcuts in the future:

{
  users(where: {
    email: { contains: "@gmail.com" },
    OR: [ organization_plan_id: { equals: "123456" }, team_plan_id: { equals: "123456" } ]
  }) {
    id
    email
  }
}

For simple cases like "these two fields equal these two values", this could be nice:

{
  users(matching: {
    plan: "123456",
    settings_planIsPublic: true
  }) {
    id
    email
  }
}

These are just some ideas I had, there's probably still a lot of room for improvement here.

jeyj0 commented

...adding onto those thoughts: when combining where and matching, it should use AND. Plus, an option for matchingAny could be added, as it's probably also a common case. Hence, the first example could be simplified to the following with the _ field accessor syntactic sugar from example 2:

{
  users(
    matchingAny: { organization_plan_id: "123456", team_plan_id: "123456" },
    where: { email: { contains: "@gmail.com" } }
  ) {
    id
    email
  }
}

Edit: an even better option to matchingAny like above would probably be a matchingOneOf (names just to distinguish the ideas) that takes an array of things it should entirely match:

{
  users(
    matchingOneOf: [ { organization_plan_id: "123456" }, { team_plan_id: "123456" } ],
    where: { email: { contains: "@gmail.com" } }
  ) {
    id
    email
  }
}