Multiple filters for related object types with a GraphQL + Absinthe Dataloader

I had a bit of a cerebral meltdown, so forgive me if this is a silly question or if it’s already been fielded somewhere.

I’ve got a GraphQL API built with Phoenix and Absinthe, and one challenge is to expose data that is coming from 2 separate databases (one Mongo, one Postgres). Conceptually, we have been thinking about this data as ONE thing, so our initial thought was to expose this as a single GraphQL Object Type. For the sake of simplicity, let’s pretend that our 2 data resources represent “Posts” (in Postgres) and “Comments” (in Mongo), and remember: for this thought experiment, we are considering Posts + Comments to be a single Object Type in GraphQL (with our particular data resources, this isn’t as silly as it sounds with the Post + Comments simplification).

If we only filter on attributes in Posts, this works fine: it’s easy enough to pull up comments related to any of the retrieved Posts, merge the data, and return it to the client.

However, things get really crazy when we try to field filtering on BOTH posts and comments – it’s basically impossible to reconcile what might be completely un-overlapping datasets being retrieved from each database. E.g. imagine searching for all posts by author X containing comments that start with “A”. In a nutshell, this “JOIN” must take place at the database layer: it can’t happen after the fact in the application layer.

I just wanted some affirmation that the problem as described is unsolvable: we’d have to either store both Posts and Comments in the same “physical” database so the filtering could be handled at the data layer, OR we would have to represent these two units of data as 2 distinct Object Types in GraphQL. Right? I feel like with a lot of effort you might be able to segregate the filter parameters that the GraphQL defined and send the relevant filters to each data resource, but… yikes, that seems like it would be really difficult (if it were possible at all), and at a minimum it would be a really brittle implementation and fraught with caveats. Would a dataloader be able to resolve this?

Thanks for any insights / thoughts!

Perhaps consider using a Postgres foreign data wrapper for Mongo? This repo may work for your use case.

1 Like

Interesting idea. I hadn’t heard of this! It does reinforce the fact that this problem has to be resolved at the data layer and it cannot be patched over by the app after the fact.

1 Like