getExecutableSchema

Returns an executable schema with data that's mocked according to the mock providers that are supplied.

const { getExecutableSchema } = require("@lola-tech/graphql-kimera");
const executableSchema = getExecutableSchema({
typeDefs,
mockProvidersFn: () => ({}), // optional
mutationResolversFn: () => ({}), // optional
mockProviders: {}, // optional
});

API

getExecutableSchema(options)

makeExecutableSchema takes a single argument: an object of options. Only the typeDefs option is required.

optionsCode
typeDefs*type Query { ...
mockProvidersFn(context) => ({ scenario: ..., builders: ... })
mutationResolversFn(store, buildMocks, context) =>
      ({ [mutationName]: (info, args, ...) => { ... } })
mockProviders{ scenario: ..., builders: ... }

We're now going to go over each option in detail.

typeDefs*

Required. A GraphQL schema language string that contains the schema definition. Putting it another way, it's what usally resides in your schema.graphql file.


mockProvidersFn

(context) => ({ scenario: ..., builders: ... })

Optional. A function that receives the resolver context as an argument and needs to return an object containing mock providers that Kimera will be using to generate mocks.

function mockProvidersFn(context) {
const mockProviders = {
// 'scenario' has the same structure as the `Query` type
scenario: {
...
},
// `builders` maps GraphQL types to functions which build mocks
// for their fields.
builders: {
Rocket: () => ({ rocketExampleField: ... }),
User: () => { ... },
...
},
};
return mockProviders;
}
note

"Mock providers" is just another way of saying "the scenario and all of the builders that were defined".


mutationResolversFn(store, buildMocks, context)

Optional. A function that returns an object that maps Mutation names to resolvers.

  • store is an object which holds all of the mocks for our schema. It defined two methods:
    • store.get(path = ''): The get method will accept an optional path string, and return the mocked value stored at that specific path.
    • store.update(path, updateValue): The update method will update the value at the supplied path with the new value. If the updated value is an object, the new value will be deeply merged over the existing value.
  • buildMocks('TypeName', scenario) is a function that mocks a specific type using existing mock providers, and optionally, a custom scenario that we can provide at execution.

You can see examples of store and buildMocks in action on the "Mocking Mutations" page.


mockProviders

Optional. An object that needs to have the same structure as the result of mockProvidersFn. These mock providers will overwrite the ones returned by mockProvidersFn by performing a deep object merge.

note

The purpose of this argument is to provide a mechanism to overwrite the default mock providers from outside of our server if need be, e.g. from a React app.

tip

It's useful to think of these as custom mock provider defintions, and the ones defined in mockProvidersFn as default defintions.

const defaultScenario = {
me: {
userName: 'c10b10',
fullName: 'John Doe'
subscribed: true,
watchList: [{}, { name: 'Barry Lyndon' }],
address: {
city: 'Bucharest',
country: 'Romania'
}
},
};
const customScenario = {
me: {
fullName: 'Alex Ciobica',
watchList: [],
address: {
city: 'Cluj-Napoca'
}
},
};
typeDefs,
mockProvidersFn: () => ({}), // optional
mutationResolversFn: () => ({}), // optional
mockProviders: {}, // optional
getExecutableSchema({
typeDefs,
mockProvidersFn: () => ({ scenario: defaultScenario }),
mockProviders: { scenario: customScenario },
});

The code above will result in having the me query have the following shape:

const defaultScenario = {
me: {
userName: "c10b10", // Default
fullName: "Alex Ciobica", // Custom
subscribed: true, // Default
watchList: [], // Custom
address: {
city: "Cluj-Napoca", // Custom
country: "Romania", // Default
},
},
};
note

When merging scenarios the array fields are overwritten, while objects are deeply merged

Builders that collide are replaced with the custom definitition.