Skip to content

Instantly share code, notes, and snippets.

@tirumaraiselvan
Last active July 31, 2023 17:05
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save tirumaraiselvan/65c6fa80542994ed6ad06fa87a443364 to your computer and use it in GitHub Desktop.
Save tirumaraiselvan/65c6fa80542994ed6ad06fa87a443364 to your computer and use it in GitHub Desktop.
Mount Hasura on Apollo federated gateway
const { ApolloServer } = require("apollo-server");
const gql = require("graphql-tag");
const fetch = require("node-fetch");
const {
introspectionQuery,
buildClientSchema,
printSchema
} = require("graphql");
const typeDefs = gql`
schema {
query: query_root
}
type _Service {
sdl: String
}
type query_root {
_service: _Service!
}
`;
const hasuraURL = "https://somehasuraurl.com/v1/graphql";
async function getHasuraSchema() {
return await fetch(hasuraURL, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({
query: introspectionQuery
})
})
.then(res => res.json())
.then(introspectionJSON => {
delete introspectionJSON.data.__schema.subscriptionType; // apollo-gateway does not support subscriptions as of now and having subscription type throws a wierd error!
return printSchema(buildClientSchema(introspectionJSON.data));
});
}
const resolvers = {
query_root: {
_service: async () => {
var hasuraSchema = await getHasuraSchema();
return { sdl: hasuraSchema };
}
}
};
const schema = new ApolloServer({ typeDefs, resolvers });
schema.listen({ port: process.env.PORT }).then(({ url }) => {
console.log(`schema ready at ${url}`);
});
@tirumaraiselvan
Copy link
Author

@manik747 Is Hasura protected via admin secret? If yes, is the Authorization header or x-hasura-admin-secret header passed to Hasura from Apollo gateway?

@darrensapalo
Copy link

darrensapalo commented Jan 17, 2021

Just leaving some notes here on my usage of this gist:

Update introspection query

I am using graphql@^15.4.0. I needed to use getIntrospectionQuery() rather than just importing introspectionQuery from graphql.

const {
  buildClientSchema,
  printSchema,
  getIntrospectionQuery
} = require("graphql");

// ....

async function getHasuraSchema() {
  return await fetch(hasuraURL, {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      query: getIntrospectionQuery()
    })
  })

@hyungta
Copy link

hyungta commented Jun 25, 2021

I get this error
Can you give me a hint to work it out?

(node:23754) UnhandledPromiseRejectionWarning: Error: A valid schema couldn't be composed. The following composition errors were found:
[hasura] Mutation -> Found invalid use of default root operation name Mutation. Mutation is disallowed when Schema.mutation is set to a type other than Mutation.
[hasura] Query -> Found invalid use of default root operation name Query. Query is disallowed when Schema.query is set to a type other than Query.
at ApolloGateway.createSchemaFromServiceList (/Users/hbkimz/Documents/works/capa/node_modules/@nestjs/graphql/node_modules/@apollo/gateway/dist/index.js:432:19)
at ApolloGateway.updateByComposition (/Users/hbkimz/Documents/works/capa/node_modules/@nestjs/graphql/node_modules/@apollo/gateway/dist/index.js:303:48)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async ApolloGateway.updateSchema (/Users/hbkimz/Documents/works/capa/node_modules/@nestjs/graphql/node_modules/@apollo/gateway/dist/index.js:279:13)
at async ApolloGateway.loadDynamic (/Users/hbkimz/Documents/works/capa/node_modules/@nestjs/graphql/node_modules/@apollo/gateway/dist/index.js:258:13)
at async ApolloGateway.load (/Users/hbkimz/Documents/works/capa/node_modules/@nestjs/graphql/node_modules/@apollo/gateway/dist/index.js:229:15)
(Use node --trace-warnings ... to show where the warning was created)
(node:23754) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:23754) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment