Express/GraphQL advice

97 views Asked by At

I'm learning GraphQL and looking for some guidance on if I'm on the right track, or if I'm just completely off base here. Essentially, I've written my backend with express-graphql and Prisma, I've seen a few different tutorials that seemed to write the types and resolvers separately using large template strings to define the schema. I followed the Net Ninja's GraphQL tutorial which used new GraphQlObjectType() to build the schema and imported all the different types into a single root query, which is then passed into the GraphQlSchema()

My confusion and question: Is this the right way to be doing this?

What I've ended up with is a very long schema file that is functional and working, but not ideal for maintenance. I've struggled to find any examples online on how to separate this code and still have it functional. I've tried exporting a file of just GraphQL object types and importing them into a schema.js file and then building my root query there but that doesn't seem to work. I've tried exporting only the fields as an object and then using the spread operator to assemble my root query, and I've tried multiple new GraphQlSchema() statements within my type files and then using graphql-tools mergeSchema to bring it all together but that didn't work either. I'm a little lost at this point and just need some guidance or an example to look at of a bigger project built in this way.

For reference, here's a snippet example to be clear on how I've built my GQL backend, to clarify the queries are working just fine, it's code maintenance here I'm gratefully looking for advice on :)

Thank you for any help or examples!

const prisma = require("../config/prismaClient");
const graphql = require('graphql');

const {
    GraphQLObjectType,
    GraphQLSchema,
    GraphQLString,
    GraphQLList } = graphql;

const UserType = new GraphQLObjectType({
    name: "User",
    fields: () => ({
        id: { type: GraphQLString },
        first_name: { type: GraphQLString },
        last_name: { type: GraphQLString },
    })
})

const BusinessType = new GraphQLObjectType({
    name: 'Business',
    fields: () => ({
        id: { type: GraphQLString },
        name: { type: GraphQLString },
        street_address: { type: GraphQLString },
    })
})

const RootQuery = new GraphQLObjectType({
    name: 'RootQueryType',
    fields: {
        users: {
            type: new GraphQLList(UserType),
            async resolve() {
                return await prisma.users.findMany();
            }
        },
        businesses: {
            type: new GraphQLList(BusinessType),
            async resolve() {
                return await prisma.businesses.findMany();
            }
        }
    }
})

module.exports = new GraphQLSchema({
    query: RootQuery
})
1

There are 1 answers

0
Saihaj On

My confusion and question: Is this the right way to be doing this?

There is no right or wrong way of writing you schema. You can use SDL (Schema definition language) which is very readable but then you need to add some dependencies to your project to set this up. GraphQL Tools has very good utilities that make it easy to write you schema.

Yes it can be little overwhelming when trying to setup these tools. I like splitting my schema and resolvers in a directory based on Type and then graphql-tools helps me merge all the resolvers and schema together into one. I found this project https://github.com/lucassus/bookshelf take a look at how they structured there graphql server https://github.com/lucassus/bookshelf/tree/master/apps/server/src/interfaces/graphql