Declarative and programmatic GraphQL

I am adopting GraphQL for new fullstack projects and I have already learned many concepts and started my first projects.

My question is related to using a declarative and graphical definition of a GraphQL schema. Basically everything I can see on the Official GraphQL site takes a declarative approach: you define the schema in one or more files, for example (thanks to this example here ):

type Brand {
  name: String
  logoUrl: String
}
enum Gender {
  MALE
  FEMALE
}
type Image {
  thumbnailUrl: String
  smallUrl: String
  mediumUrl: String
  largeUrl: String
}
type Article {
  id: ID! # non-nullable, is guaranteed to exist on every article
  name: String
  thumbnailUrl: String
  brand: Brand
  genders: [Gender]
  images: [Image]
  recommendations: [Article]
}
type Query {
  Article(id: ID!): Article
  Articles: [Articles]
}

      

Very clean and concise code even for complex data structures.

But most of the examples I see on the internet, and even the books I have studied, take a programmatic approach to constructing the circuit, for example:

import { GraphQLObjectType, GraphQLInputObjectType } from 'graphql';
import {GraphQLNonNull, GraphQLID, GraphQLList } from 'graphql';
import { GraphQLString, GraphQLInt, GraphQLBoolean } from 'graphql';

import { UserType } from '../User/types';
import UserModel from '../../../models/User';

const fields = {
    _id: {
        type: new GraphQLNonNull(GraphQLID)
    },
    name: {
        type: GraphQLString
    },
    phone: {
        type: GraphQLString
    }
 };

const CompanyType = new GraphQLObjectType({
    name: 'Company',
    description: 'Company',
    fields: fields
 })


const Company = {
    type: CompanyType,
    description: 'Get single company',
    args: {
        id: {
            name: 'id',
            type: new GraphQLNonNull(GraphQLID)
        }
    },
    resolve(root, params) {

        params.deleted = false;

        return CompanyModel.find(params).exec();
    }
}

const Companies = {
    type: new GraphQLList(CompanyType),
    description: 'Get all companies',
    resolve(root) {
        const companies = CompanyModel.find({ deleted: false }).exec();
        if (!companies) {
            throw new Error('Error getting companies.')
        }
        return companies;   
    }
}

export default {
    Company,
    Companies
}

      

My goal is to build a large SaaS application, so the schema is going to be quite complex and I'm afraid the code will soon get complicated.

So, should I use a declarative approach, a programmatic approach, or a combination of the two?

What are the best practices here?

+3


source to share


2 answers


This section has a good discussion here and here .

IMHO, the biggest benefit to defining your schema in GraphQL schema language is readability. This makes your diagram easier to read and understand, especially for internal users who may request the endpoint but are not actually involved in developing it. I think this also makes the definition and modification of the schema less error prone.

On the other hand, defining a schema with software provides much more flexibility. For example, if you are using buildSchema

, you are limited to passing to resolvers only for your requests and mutations. This works great if you're fine with each type using only the default resolver, but what happens when you need to define converters for individual fields?



Defining a schema programmatically allows you to define converters for individual fields in any of the types you specify. Not only does this help transform the data you return from your database (by turning it thumbanail_url

into a field thumbnailUrl

), but if those fields require additional queries to the database, it prevents them from being disabled if the field is not actually there, which can be a significant performance boost. As the documentation points out, this approach is also useful if you want to automatically generate a schema.

Personally, I love graphql-tools

makeExecutableSchema . This is a kind of "middle class" approach that allows you to define your types very easily (using the GraphQL schema language) while still providing flexibility in implementing solutions.

+3


source


You can use the library merge-graphql-schemas

for better circuit design. This post demonstrates how to modulate your graphql schemas using a library and providing a seed project that you can clone. Hope it helps! :)



0


source







All Articles