So I have this two schemas
Schema1
type Permission {
relation: Relation
}
enum Relation {
ONE
TWO
THREE
}
Schema2
type Permission {
relation: Relation
}
enum Relation {
FOUR
FIVE
SIX
}
The expect result is something similar to: (but I'm open to different ideas) The queries I would like to make after the merge are:
{
permissions{
relation
}
}
And get a result like
"permissions": [
{
"relation": "ONE"
},
{
"relation": "SIX"
}
]
or
"permissions": [
{
"relation": "schema1ONE"
},
{
"relation": "schema2SIX"
}
]
And mutations like:
mutation{
createPermission(
relation: ONE
){
relation
}
}
mutation{
createPermission(
relation: SIX
){
relation
}
}
or
mutation{
createPermission(
relation: schema1ONE
){
relation
}
}
mutation{
createPermission(
relation: schema2SIX
){
relation
}
}
I'm trying using the transformSchema
function on graphql-tools but can't quite figure it out correctly:
const Schema1 = await getRemoteSchema('schema1_url', 'schema1');
const Schema2 = await getRemoteSchema('schema2_url', 'schema2');
const schemas = [Schema1, Schema2]
const schema = mergeSchemas({
schemas: schemas,
resolvers: {}
});
getRemoteSchema definition
export const getRemoteSchema = async (uri: string, schemaName: string): Promise<GraphQLSchema> => {
const httpLink = new HttpLink({ uri, fetch });
const schema = await introspectSchema(httpLink);
const executableSchema = makeRemoteExecutableSchema({
schema,
httpLink,
});
// transform schema by renaming root fields and types
const renamedSchema = transformSchema(
executableSchema,
[
new RenameTypes(name => {
if (name == 'Relation') {
return schemaName + name
} else {
return name
}
}),
// new RenameRootFields((operation, name) => `${schemaName}_${name}`)
]
);
return renamedSchema;
}
I made this glitch https://glitch.com/edit/#!/schema-stitching-conflict So it's easier to see the problem.
You need both RenameTypes
and RenameRootFields
transforms,
RenameTypes
to transform the typenames
from: Permission
and Relation
(The colliding types),
to: schema1_Permission
, schema2_Permission
and: schema1_Relation
, schema1_Relation
RenameRootFields
to transform the Query names for those types
from: permission(id: ID!): Permission
to: schema1_permission(id: ID!): schema1_Permission
and schema2_permission(id: ID!): schema2_Permission
and: permissions: [Permission]
to: schema1_permissions: [schema1_Permission]
and schema2_permissions: [schema2_Permission]
The transform would be something like:
const {
makeExecutableSchema,
addMockFunctionsToSchema,
transformSchema,
RenameTypes,
RenameRootFields
} = require('graphql-tools');
const schema1 = makeExecutableSchema({
typeDefs: `
type Permission {
id: ID!
text: String
relation: Relation
}
type Query {
permissions: [Permission]
permission(id: ID!): Permission
}
enum Relation {
ONE
TWO
THREE
}
`
});
addMockFunctionsToSchema({ schema: schema1 });
const renamedSchema1 = transformSchema(
schema1,
[
new RenameTypes(name => {
if (name == 'Relation' || name == 'Permission') {
return 'schema1_' + name
} else {
return name
}
}, { renameBuiltins: false, renameScalars: true }),
new RenameRootFields((_op, name) => {
return name.includes('ermission') ? `schema1_${name}` : name
})
]
);
references: https://www.apollographql.com/docs/graphql-tools/schema-transforms/ https://www.apollographql.com/docs/graphql-tools/schema-stitching/