We use GraphQL transformers. Examples are Graphback, Dgraph, AWS Amplify. This library provides function that given any GraphQL schema creates new GraphQL schemas basing on transformer functions.
npm i transform-graphql
Provide original schema with your transformer directives and an array of transformer functions defined by TransformerDef
type
import { TransformGraphQLSchema } from 'transform-graphql';
const transformedSchema = TransformGraphQLSchema({
schema: inputSchema,
transformers: [transformerCRUD]
});
This short example simply shows what transform GraphQL is about:
Given the schema:
type Post @model{
name: String!
content: String!
createdAt: String!
}
type Query{
version:String
}
type Mutation{
version:String
}
directive @model on OBJECT
where model is our actual transformer
We expect schema to be transformed into
directive @model on OBJECT
input CreatePost{
name: String!
content: String!
createdAt: String!
}
input DetailsPost{
id: String!
}
type Mutation{
version: String
post: PostMutation
}
type Post @model{
name: String!
content: String!
createdAt: String!
}
type PostMutation{
create(
post: CreatePost
): String!
update(
post: UpdatePost
details: DetailsPost
): String!
remove(
details: DetailsPost
): String!
}
type PostQuery{
list: [Post!]!
getByDetails(
details: DetailsPost
): Post
}
type Query{
version: String
post: PostQuery
}
input UpdatePost{
name: String!
content: String!
createdAt: String!
}
schema{
query: Query,
mutation: Mutation
}
And the transformer code should look like this
const inputSchema = `
type Post @model{
name: String!
content: String!
createdAt: String!
}
type Query{
version:String
}
type Mutation{
version:String
}`
const transformerCRUD: TransformerDef = {
transformer: ({ field, operations }) => {
if (!field.args) {
throw new Error('Model can be used only for types');
}
if (!operations.query) {
throw new Error('Query type required');
}
if (!operations.mutation) {
throw new Error('Query type required');
}
return `
input Create${field.name}{
${TreeToGraphQL.parse({ nodes: field.args })}
}
input Update${field.name}{
${TreeToGraphQL.parse({ nodes: field.args })}
}
input Details${field.name}{
id: String!
}
type ${field.name}Query{
list: [${field.name}!]!
getByDetails(details: Details${field.name}): ${field.name}
}
type ${field.name}Mutation{
create( ${field.name[0].toLowerCase() + field.name.slice(1)}: Create${field.name} ): String!
update( ${field.name[0].toLowerCase() + field.name.slice(1)}: Update${field.name}, details: Details${
field.name
} ): String!
remove( details: Details${field.name} ): String!
}
extend type ${operations.query.name}{
${field.name[0].toLowerCase() + field.name.slice(1)}: ${field.name}Query
}
extend type ${operations.mutation.name}{
${field.name[0].toLowerCase() + field.name.slice(1)}: ${field.name}Mutation
}
`;
},
directiveName: 'model',
};
const transformedSchema = TransformGraphQLSchema({ schema: GraphQLTransform, transformers: [transformerCRUD] });
//transfomed schema should look like in the example
- provide CLI
- provide examples