npm package: @subql/x-postgraphile-core
Description: <span class="badge-patreon"><a href="https://patreon.com/benjie" title="Support Graphile development on Patreon"><img src="https://img.shields.io/badge/sponsor-via%20Patreon-orange.svg" alt="Patreon sponsor button" /></a></span> [![Discord chat room](http
Author: Benjie Gillam
Latest version: 4.13.0-0.2.0

# postgraphile-core

<span class="badge-patreon"><a href="https://patreon.com/benjie" title="Support Graphile development on Patreon"><img src="https://img.shields.io/badge/sponsor-via%20Patreon-orange.svg" alt="Patreon sponsor button" /></a></span>
[![Discord chat room](https://img.shields.io/discord/489127045289476126.svg)](http://discord.gg/graphile)
[![Package on npm](https://img.shields.io/npm/v/postgraphile-core.svg?style=flat)](https://www.npmjs.com/package/postgraphile-core)
![MIT license](https://img.shields.io/npm/l/postgraphile-core.svg)
[![Follow](https://img.shields.io/badge/twitter-@GraphileHQ-blue.svg)](https://twitter.com/GraphileHQ)

This module is the compatibility between the web layer of
[PostGraphile](https://graphile.org/postgraphile/) and the GraphQL schema
built with Graphile Engine. It loads the relevant `graphile-build-pg` plugins
and augments the inflector depending on the PostGraphile options provided.

<!-- SPONSORS_BEGIN -->

## Crowd-funded open-source software

To help us develop this software sustainably under the MIT license, we ask
all individuals and businesses that use it to help support its ongoing
maintenance and development via sponsorship.

### [Click here to find out more about sponsors and sponsorship.](https://www.graphile.org/sponsor/)

And please give some love to our featured sponsors 🤩:

<table><tr>
<td align="center"><a href="https://surge.io/"><img src="https://graphile.org/images/sponsors/surge.png" width="90" height="90" alt="Surge" /><br />Surge</a> *</td>
<td align="center"><a href="https://www.netflix.com/"><img src="https://graphile.org/images/sponsors/Netflix.png" width="90" height="90" alt="Netflix" /><br />Netflix</a> *</td>
<td align="center"><a href="https://www.the-guild.dev/"><img src="https://graphile.org/images/sponsors/theguild.png" width="90" height="90" alt="The Guild" /><br />The Guild</a> *</td>
<td align="center"><a href="https://qwick.com/"><img src="https://graphile.org/images/sponsors/qwick.png" width="90" height="90" alt="Qwick" /><br />Qwick</a> *</td>
</tr><tr>
<td align="center"><a href="http://chads.website"><img src="https://graphile.org/images/sponsors/chadf.png" width="90" height="90" alt="Chad Furman" /><br />Chad Furman</a> *</td>
<td align="center"><a href="https://dovetailapp.com/"><img src="https://graphile.org/images/sponsors/dovetail.png" width="90" height="90" alt="Dovetail" /><br />Dovetail</a> *</td>
<td align="center"><a href="https://www.enzuzo.com/"><img src="https://graphile.org/images/sponsors/enzuzo.png" width="90" height="90" alt="Enzuzo" /><br />Enzuzo</a> *</td>
<td align="center"><a href="https://stellate.co/"><img src="https://graphile.org/images/sponsors/Stellate.png" width="90" height="90" alt="Stellate" /><br />Stellate</a> *</td>
</tr></table>

<em>\* Sponsors the entire Graphile suite</em>

<!-- SPONSORS_END -->

## Should you be here?

Unless you want to use the low-level API you probably want to go to the
PostGraphile (previously 'PostGraphQL') repository instead:
[https://github.com/graphile/postgraphile](https://github.com/graphile/postgraphile)

It's suitable to use this module in your own application, but please be aware you
need to bring your own security in the form of an authenticated `pgClient` (see
below).

For more information about PostGraphile and Graphile Engine please see the
documentation at [graphile.org](https://www.graphile.org/).

## `createPostGraphileSchema(pgConfig, schemas, options)`

This is the function you're most likely to use in production, it will return
a promise to a GraphQL schema. You are responsible in for implementing
security by passing a pre-authenticated `pgClient` inside the GraphQL
`context` when you resolve a GraphQL query or mutation.

Example:

```js
const schema = await createPostGraphileSchema(
  process.env.DATABASE_URL,
  ["users_schema", "posts_schema"],
  {
    dynamicJson: true,
    pgJwtSecret: process.env.JWT_SECRET,
    pgJwtTypeIdentifier: "users_schema.jwt_type",
  }
);
```

Full example:

```js
const { createPostGraphileSchema } = require("postgraphile-core");
const { graphql } = require("graphql");
const pg = require("pg");

// Create a postgres pool for efficiency
const pgPool = new pg.Pool({
  connectionString: process.env.DATABASE_URL,
});

async function runQuery(query, variables) {
  // Generate our schema using the default plugins against DATABASE_URL,
  // introspecting the two schemas specified with the options provided.
  //
  // Normally for performance you'd only do this once for your entire
  // application run, not once per query as it is here.
  const schema = await createPostGraphileSchema(
    process.env.DATABASE_URL,
    ["app_public"],
    {
      dynamicJson: true,
      pgJwtSecret: process.env.JWT_SECRET,
      pgJwtTypeIdentifier: "users_schema.jwt_type",
    }
  );

  // Fetch a postgres client from the pool
  const pgClient = await pgPool.connect();

  // Start a transaction so we can apply settings local to the transaction
  await pgClient.query("begin");

  try {
    // The following statement is equivalent to (but faster than):
    //    await pgClient.query("set local role to 'postgraphile_user'");
    //    await pgClient.query("set local jwt.claims.user_id to '27'");
    await pgClient.query(`select
      set_config('role', 'postgraphile_user', true),
      set_config('jwt.claims.user_id', '27', true)
    `);
    return await graphql(
      schema,
      query,
      null,
      /* CONTEXT > */ {
        pgClient: pgClient,
      } /* < CONTEXT */,
      variables
    );
  } finally {
    // commit the transaction (or rollback if there was an error) to clear the local settings
    await pgClient.query("commit");

    // Release the pgClient back to the pool.
    await pgClient.release();
  }
}

// Normally you'd execute a query in response to an HTTP request or similar
runQuery(
  // This query obviously depends on your database schema
  "query MyQuery { allPosts { nodes { id, title, author: userByAuthorId { username } } } }"
)
  .then(result => {
    console.dir(result);
    pgPool.end();
  })
  .catch(e => {
    console.error(e);
    process.exit(1);
  });
```

To see how this works in a real application, check out
[`withPostGraphileContext` in
PostGraphile](https://github.com/graphile/postgraphile/blob/master/src/postgraphile/withPostGraphileContext.ts)

## `watchPostGraphileSchema(pgConfig, schemas, options, onNewSchema)`

This function is useful in development; it returns a promise that resolves to a
`release` function that you can call to stop watching. The `onNewSchema`
callback will be called every time a new schema is generated, and it is
guaranteed to be called before the returned promise resolves. Other than the
additional `onNewSchema` option, the options are identical to that of
`createPostGraphileSchema` above.