How to get query result from postgraphile running as a library

630 views Asked by At

I have postgraphile running as an express middleware. For example:

const pgMiddleware = postgraphile(pool, SCHEMA, postgraphileConfig);

app.use(pgMiddleware);

How to get or intercept the result of a query or mutation without having a separate client?

For example when I send the below query

query {
 personById(id: 1){
  firstname
  }
}

I want to be able to get the data sent back inside the same express app. How can I do that?

1

There are 1 answers

0
THX1138 On

I believe what you are asking for is to be able to execute GraphQL operations against a PostGraphile schema from other routes/middlewares in Express without needing to make additional http requests. This is called schema only usage and you will specifically want to use withPostGraphileContext to execute your request and process results:

import type { Express } from "express";
import type { Pool } from "pg";
import {
  gql,
  makeProcessSchemaPlugin,
  postgraphile,
  withPostGraphileContext,
} from "postgraphile";
import PgSimplifyInflectorPlugin from "@graphile-contrib/pg-simplify-inflector";
import type { GraphQLSchema } from "graphql";
import { graphql } from "graphql";

// Register your middlewares with express
const schemaOnlyUsageApp = (app: Express, pool: Pool) => {
  let schema: GraphQLSchema;

  // This plugin will execute a callback each time the PostGraphile
  // GraphQl schema is rebuit.
  const schemaProcessorPlugin = makeProcessSchemaPlugin((newSchema) => {
    schema = newSchema;
    return schema;
  });

  // Register the PostGraphile middleware as normal for requests on /graphql (and /graphiql)
  app.use(
    postgraphile(pool, "my_schema", {
      simpleCollections: "omit",
      dynamicJson: true,
      legacyRelations: "omit",
      setofFunctionsContainNulls: false,
      appendPlugins: [PgSimplifyInflectorPlugin, schemaProcessorPlugin],
      watchPg: true,
      graphiql: true,
      enhanceGraphiql: true,
      showErrorStack: true,
      allowExplain: true,
    })
  );

  // custom route that will execute a predefined gql query directly against the schema
  app.get("/posts", async (req, res) => {
    // arbitrary gql query
    const query = gql`
      query posts {
        posts {
          edges {
            node {
              id
              title
              body
              likeCount
              createdAt
            }
          }
        }
      }
    `;

    const result = await withPostGraphileContext(
      {
        // Reuse your pool to avoid creating additional connections
        pgPool: pool,
      },
      async (context) => {
        // execute your query directly and get results without making
        // an additional http request!
        const queryResult = await graphql({
          schema,
          source: query.loc?.source || "",
          contextValue: { ...context },
        });
        return queryResult;
      }
    );

    res.send(result);
  });
};

export default schemaOnlyUsageApp;