split graphQL initialization step and published the executable schema

This commit is contained in:
eric-burel 2018-11-19 11:37:04 +01:00
parent 8e3d6b8d0d
commit 8d1f5fb92b
9 changed files with 135 additions and 72 deletions

View file

@ -359,13 +359,31 @@ export const GraphQLSchema = {
}
return graphQLSchema;
},
// getters
getSchema() {
if (!(this.finalSchema && this.finalSchema.length)) {
throw new Error('Warning: trying to access schema before it has been created by the server.')
}
return this.finalSchema[0]
},
getExecutableSchema() {
if (!this.executableSchema) {
throw new Error('Warning: trying to access executable schema before it has been created by the server.')
}
return this.executableSchema
}
};
Vulcan.getGraphQLSchema = () => {
if (!GraphQLSchema.finalSchema) {
throw new Error('Warning: trying to access graphQL schema before it has been created by the server.')
}
const schema = GraphQLSchema.finalSchema[0];
// eslint-disable-next-line no-console
console.log(schema);
// console.log(schema);
return schema;
}

View file

@ -3,7 +3,6 @@
* @see https://www.apollographql.com/docs/apollo-server/migration-two-dot.html
*/
import { makeExecutableSchema } from 'apollo-server';
// Meteor WebApp use a Connect server, so we need to
// use apollo-server-express integration
//import express from 'express';
@ -11,23 +10,22 @@ import { ApolloServer } from 'apollo-server-express';
import { Meteor } from 'meteor/meteor';
import { GraphQLSchema } from '../../modules/graphql.js';
import { WebApp } from 'meteor/webapp';
import { runCallbacks } from '../../modules/callbacks.js';
// import cookiesMiddleware from 'universal-cookie-express';
// import Cookies from 'universal-cookie';
import voyagerMiddleware from 'graphql-voyager/middleware/express';
import getVoyagerConfig from './voyager';
export let executableSchema;
import initGraphQL from './initGraphQL'
import './settings';
import { engineConfig } from './engine';
import { defaultConfig, defaultOptions } from './defaults';
import { initContext, computeContextFromReq } from './context.js';
import getPlaygroundConfig from './playground';
import { GraphQLSchema } from '../../modules/graphql.js';
// SSR
import { ssrMiddleware } from '../apollo-ssr'
/**
@ -117,70 +115,10 @@ const createApolloServer = ({ options: givenOptions = {}, config: givenConfig =
// createApolloServer when server startup
Meteor.startup(() => {
runCallbacks('graphql.init.before');
// typeDefs
const generateTypeDefs = () => [
`
scalar JSON
scalar Date
${GraphQLSchema.getAdditionalSchemas()}
${GraphQLSchema.getCollectionsSchemas()}
type Query {
${GraphQLSchema.queries
.map(
q =>
`${
q.description
? ` # ${q.description}
`
: ''
} ${q.query}
`
)
.join('\n')}
}
${
GraphQLSchema.mutations.length > 0
? `type Mutation {
${GraphQLSchema.mutations
.map(
m =>
`${
m.description
? ` # ${m.description}
`
: ''
} ${m.mutation}
`
)
.join('\n')}
}
`
: ''
}
`
];
const typeDefs = generateTypeDefs();
GraphQLSchema.finalSchema = typeDefs;
executableSchema = makeExecutableSchema({
typeDefs,
resolvers: GraphQLSchema.resolvers,
schemaDirectives: GraphQLSchema.directives
});
initGraphQL() // define executableSchema
createApolloServer({
options: {
schema: executableSchema
schema: GraphQLSchema.executableSchema
}
// config: ....
// contextFromReq: ....

View file

@ -0,0 +1,83 @@
/**
* Init the graphQL schema
*/
import { makeExecutableSchema } from 'apollo-server';
import { GraphQLSchema } from '../../modules/graphql.js';
import { runCallbacks } from '../../modules/callbacks.js';
const getQueries = () => (
`type Query {
${GraphQLSchema.queries
.map(
q =>
`${
q.description
? ` # ${q.description}
`
: ''
} ${q.query}
`
)
.join('\n')}
}
`
)
const getMutations = () => GraphQLSchema.mutations.length > 0 ? (
`
${
GraphQLSchema.mutations.length > 0
? `type Mutation {
${GraphQLSchema.mutations
.map(
m =>
`${
m.description
? ` # ${m.description}
`
: ''
} ${m.mutation}
`
)
.join('\n')}
}
`
: ''
}
`
) : ''
// typeDefs
const generateTypeDefs = () => [
`
scalar JSON
scalar Date
${GraphQLSchema.getAdditionalSchemas()}
${GraphQLSchema.getCollectionsSchemas()}
${getQueries()}
${getMutations()}
`
];
const initGraphQL = () => {
runCallbacks('graphql.init.before');
const typeDefs = generateTypeDefs();
const executableSchema = makeExecutableSchema({
typeDefs,
resolvers: GraphQLSchema.resolvers,
schemaDirectives: GraphQLSchema.directives
});
GraphQLSchema.finalSchema = typeDefs;
GraphQLSchema.executableSchema = executableSchema;
return executableSchema
}
export default initGraphQL

View file

@ -10,15 +10,15 @@ import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { SchemaLink } from 'apollo-link-schema';
// TODO: how to import the schema?
import { GraphQLSchema } from '../../modules/graphql'
const schema = {} // TODO ???
import { GraphQLSchema } from '../../modules/graphql.js';
// @see https://www.apollographql.com/docs/react/features/server-side-rendering.html#local-queries
// import { createHttpLink } from 'apollo-link-http';
// import fetch from 'node-fetch'
const createClient = (req) => {
// we need the executable schema
const schema = GraphQLSchema.getExecutableSchema()
const client = new ApolloClient({
ssrMode: true,
link: new SchemaLink({ schema }),

View file

@ -63,4 +63,5 @@ Package.onUse(function(api) {
Package.onTest(function(api) {
api.use(['ecmascript', 'meteortesting:mocha', 'vulcan:lib']);
api.mainModule('./test/index.js');
api.mainModule('./test/server/index.js', 'server');
});

View file

@ -0,0 +1,22 @@
import expect from 'expect'
import { GraphQLSchema } from '../../lib/modules/graphql'
import initGraphQL from '../../lib/server/apollo-server/initGraphQL'
describe('vulcan:lib/graphql', function(){
// TODO: handle the graphQL init better to fix those tests
it.skip('throws if graphql schema is not initialized', function(){
expect(() => GraphQLSchema.getSchema()).toThrow()
})
it.skip('throws if executable schema is not initialized', function(){
expect(() => GraphQLSchema.getExecutableSchema()).toThrow()
})
it('can access the graphql schema', function(){
initGraphQL()
expect(GraphQLSchema.getSchema()).toBeDefined()
})
it('can access the executable graphql schema', function(){
initGraphQL()
expect(GraphQLSchema.getExecutableSchema()).toBeDefined()
})
})

View file

@ -0,0 +1 @@
import './graphql.test'