graphqlapollo-clientpostgraphile

Accessing Postgraphile (as a library) with Apollo client from the same server


I have postgraphile running on an express server (as a library)

export const postGraphileServer = () => {
  return postgraphile(process.env.DB_DSN, 'public', options);
};

Express:

app.use(postGraphileServer());

Using the codegen introspection plugin I am generating a graphql.schema.json and everything works correctly when GQL is accessed externally via an http link. yml snippit:

  packages/graphql/src/generated/graphql.schema.json:
    plugins:
      - 'introspection'

I have a use case for exposing a REST endpoint on the express server which would take a payload and create a row in Postgres. What I would like to do is access Postgraphile directly (without a network hop) to avoid auth - I believe using schema only

From what I have read the way to do this is via a SchemaLink. I've tried something like:

const clientSchema = buildClientSchema(schema as unknown as IntrospectionQuery);

// Make executable schema from client schema
const executableSchema = makeExecutableSchema({
  typeDefs: clientSchema,
});

return (this.#_apolloClient = new ApolloClient({ 
  ssrMode: true,
  link: new SchemaLink({ schema: executableSchema }),
  cache: new InMemoryCache(),
}));

Where schema is the codegen generated graphql.schema.json file. I believe the issue I have is I also need to pass the resolvers to makeExecutableSchema so that Postgraphile knows how to query / mutate - currently it silently fails but does nothing.

Am I on the correct path here and is there a way to access the generated resolvers from postgraphile (or do I need to manually create them for this specific use case?)


Solution

  • Ok, so with the help of Benjie I was able to get this working using GraphileApolloLink.ts. Since this link grabs the context and schema from the middleware itself, there is no need to try and build a schema from the schema.graphql.json introspection file.

    My requirements differed slightly so I removed the mutation check inside GraphileApolloLink.ts.

    For completeness, I was able to initialize the ApolloClient with simply

    get #apolloClient(): ApolloClient<NormalizedCacheObject> {
      if (this.#_apolloClient) {
        return this.#_apolloClient;
      }
    
      const _link = new GraphileApolloLink({
        req: this.request,
        res: this.response,
        // Getter for the middleware object passed into Express
        postgraphileMiddleware: postGraphileMiddleware(),
      });
    
      return (this.#_apolloClient = new ApolloClient({
        ssrMode: true,
        link: _link,
        cache: new InMemoryCache(),
      }));
    }
    

    And query the data successfully using the queries/mutations generated by codegen as expected.