Postgraphile: schema.json for babel-relay-plugin

Created on 27 May 2016  ·  15Comments  ·  Source: graphile/postgraphile

I was under the impression that I need a schema.json to transpile the relay queries — https://github.com/relayjs/relay-starter-kit/blob/master/build/babelRelayPlugin.js. However I don’t see how I would accomplish this with postgraphql. _Am I missing something obvious?_ Could someone point me in the right direction. I am also curious what the status of https://github.com/calebmer/postgraphql/pull/49 is?

PS. Thanks for this great project.

Most helpful comment

Maybe helpful to others,

import fs from 'fs';
import path from 'path';
import { createGraphqlSchema } from 'postgraphql';
import 'postgraphql/dist/promisify';
import { graphql } from 'graphql';
import { introspectionQuery } from 'graphql/utilities';

(async () => {
  const schema = await createGraphqlSchema('postgres://localhost:5432/your_db', 'your_schema')
    .catch(err => console.error(err));
  const result = await graphql(schema, introspectionQuery)
    .catch(err => console.error(err));

  if (result.errors) {
    console.error('ERROR introspecting schema: ', result.errors);
  } else {
    fs.writeFileSync(
      path.join(__dirname, '../schema.json'),
      JSON.stringify(result, null, 2)
    );
  }
})().catch(err => console.error(err));

Lessons learned, dont forget your catch handlers … ☺️

All 15 comments

Thank you @ferdinandsalis 😊

Use the introspection query here to get the schema.json file.

As for #49, it's done in its most basic form. There is some mutation stuff and implementing node for viewer which still is yet to be done. If the basic form is enough for you, I can merge it and we can work out the intricacies later.

@calebmer thanks, yes do merge, however to be honest I am not sure if the basic form is enough for me. I have just started using postgresql and relay. I will give it a try.

@calebmer is this what you had in mind? I have tried and it returns an introspection error (see bottom).

import fs from 'fs';
import path from 'path';
import { createGraphqlSchema } from 'postgraphql';
import { graphql } from 'graphql';
import { introspectionQuery, printSchema } from 'graphql/utilities';

(async () => {
  const schema = await createGraphqlSchema('postgres://localhost:5432', 'some_schema')
  const result = await (graphql(schema, introspectionQuery));
  if (result.errors) {
    console.error(
      'ERROR introspecting schema: ',
      JSON.stringify(result.errors, null, 2)
    );
  } else {
    fs.writeFileSync(
      path.join(__dirname, '../schema.json'),
      JSON.stringify(result, null, 2)
    );
  }
})();

the contents of result.errors:

ERROR introspecting schema:  [
  {}
]

Thanks for your help.

I have tried the same with your forum_example. I get the same nondescript error. Might just be me ofcourse 😉.

Here is the gist of the schema output that I logged from the forum example —https://gist.github.com/ferdinandsalis/2215fb51378f2a3f25b458ac24884392

I'd recommend trying to run the introspection query either in GraphiQL, or directly send a request to the HTTP endpoint. There is some context values that might be missing here causing the query to fail.

This is not a use case I was originally planning to support, I'd have to look deeper at what's causing things to fail.

That said, here's some tips for debugging 😉

  • Don't stringify result.errors when you log it to the console. There may be some fields the JSON serialization is stripping away.
  • Look here and here for an example of how we use createGraphqlSchema internally.

Thanks again. Hopefully I will make it work ☺️. I would hate to go down my the original road rebuilding parts of postgraphql. Which seems just wrong … considering my expertise 😅

I have added a catch handler to the promise returned from createGraphqlSchema function and got the following error: [TypeError: _pg2.default.connectAsync is not a function]. So I guess the pg instance is not promisified in this case?!

@calebmer have you seen https://github.com/vitaly-t/pg-promise which provides a very nice promise based layer for node-postgres.

This was the problem https://github.com/calebmer/postgraphql/issues/55#issuecomment-222306467. Importing promisify in the script solved the problem. Schema was created. However maybe it makes more sense to get the schema from the http endpoint as you pointed out. I will need to test that.

Maybe helpful to others,

import fs from 'fs';
import path from 'path';
import { createGraphqlSchema } from 'postgraphql';
import 'postgraphql/dist/promisify';
import { graphql } from 'graphql';
import { introspectionQuery } from 'graphql/utilities';

(async () => {
  const schema = await createGraphqlSchema('postgres://localhost:5432/your_db', 'your_schema')
    .catch(err => console.error(err));
  const result = await graphql(schema, introspectionQuery)
    .catch(err => console.error(err));

  if (result.errors) {
    console.error('ERROR introspecting schema: ', result.errors);
  } else {
    fs.writeFileSync(
      path.join(__dirname, '../schema.json'),
      JSON.stringify(result, null, 2)
    );
  }
})().catch(err => console.error(err));

Lessons learned, dont forget your catch handlers … ☺️

Yep, ok, maybe time to migrate to pg-promise. I thought importing postgraphql also brought in the promisfy module. Oops 😊

@calebmer _if_ you migrate to pg-promise take note of https://github.com/vitaly-t/pg-monitor.

My version using latest 'createPostGraphQLSchema' and async/await... This is a modified version of whats found at https://github.com/lvarayut/relay-fullstack

/* eslint-disable no-console */
import path from 'path';
import fs from 'fs';
import { graphql } from 'graphql';
import chalk from 'chalk';
import { introspectionQuery, printSchema } from 'graphql/utilities';
import config from '../config/environment';
import { createPostGraphQLSchema } from 'postgraphql';


const jsonFile = path.join(__dirname, '../data/schema.json');
const graphQLFile = path.join(__dirname, '../data/schema.graphql');

async function updateSchema() {
  try {
    const schema = await createPostGraphQLSchema(config.postgres.url, config.postgres.schema);
    const json = await graphql(schema, introspectionQuery);
    fs.writeFileSync(jsonFile, JSON.stringify(json, null, 2));
    fs.writeFileSync(graphQLFile, printSchema(schema));
    console.log(chalk.green('Schema has been regenerated'));
  } catch (err) {
    console.error(chalk.red(err.stack));
  }
}

// Run the function directly, if it's called from the command line
if (!module.parent) updateSchema();

export default updateSchema;

A feature for auto-exporting the schema was added in 3.0.0 thanks to @MaienM :tada:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tazsingh picture tazsingh  ·  3Comments

k-ogawa-1988 picture k-ogawa-1988  ·  3Comments

CarlFMateus picture CarlFMateus  ·  4Comments

mrbarletta picture mrbarletta  ·  5Comments

calebmer picture calebmer  ·  3Comments