In Postgraphile, How Can I Simplify the API?

Viewed 383

Using Postgraphile, let's say I am querying all Foos, ie. allFoosList. Let's also say my Foo table has a many-to-many relationship with a Bar table in my database (ie. my Foos have Bars).

In my results I will get back an array of Foo objects. Those objects will have a property that is an array of Bars. However, that field won't be bars or barsByBarIdList ... it will have a name like barFoosByFooIdList. The objects inside that array will have a barByBarId property, which will have the actual record values.

Is there a way for me to correct/simplify this?

1 Answers

There's a number of approaches, a couple of which are documented in PostGraphile's documentation under Relations > Many-to-many relations.

Computed column

create function foos_bars(f foos) returns setof bars as $$
  select bars.*
  from bars
  inner join foo_bars
  on foo_bars.bar_id = bars.id
  where foo_bars.foo_id = f.id
$$ language sql stable;

Schema extension

const { makeExtendSchemaPlugin, gql, embed } = require("graphile-utils");

module.exports = makeExtendSchemaPlugin(build => {
  const { pgSql: sql } = build;
  return {
    typeDefs: gql`
      extend type Foo {
        bars: BarsConnection @pgQuery(
          source: ${embed(sql.fragment`bars`)}
          withQueryBuilder: ${embed((queryBuilder, args) => {
            queryBuilder.where(
              sql.fragment`exists(select 1 from foo_bars where foo_bars.bar_id = ${queryBuilder.getTableAlias()}.id and foo_bars.foo_id = ${queryBuilder.parentQueryBuilder.getTableAlias()}.id`
            );
          })}
        )
      }
    `,
  };
});

(This is more performant, but somewhat harder to read - we're hoping to optimise this syntax in future).

Contrib many-to-many plugin

yarn add @graphile-contrib/pg-many-to-many
postgraphile --append-plugins @graphile-contrib/pg-many-to-many

You can also optimize the naming

We provide a pg-simplify-inflector plugin that can be used to simplify names in your schema if you're pretty sure there'll be no conflicts; I highly recommend it's usage if your database schema is well defined:

https://github.com/graphile/pg-simplify-inflector

Related