声明式与编程式GraphQL

Men*_*des 5 javascript graphql

我正在为新的fullstack项目采用GraphQL,我已经研究了许多概念并开始了我的第一个项目.

我的问题与使用声明性和编程式GraphQL模式定义有关.基本上我在GraphQL官方网站上看到的使用声明性方法:你在一个或多个文件中定义模式(感谢这里的例子):

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]
}
Run Code Online (Sandbox Code Playgroud)

即使对于某种复杂的数据结构,代码也非常简洁明了.

但是我在网络上看到的大多数例子,甚至在我研究的书籍上都使用编程方法来构建模式,例如:

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
}
Run Code Online (Sandbox Code Playgroud)

我的目标是构建一个大型SaaS应用程序,因此架构将变得相当复杂,我担心代码很快就会变得复杂.

那么,我应该采用声明式方法,以编程方式处理还是两种方式混合使用?

这里的最佳做法是什么?

Dan*_*den 6

这里这里有关于这个主题的很多讨论.

恕我直言,用GraphQL模式语言定义模式的最大优点是可读性.它使您的模式易于阅读和理解,特别是对于可能正在查询端点但实际上没有参与其设计的内部用户.我认为这也使得定义和更改模式更不容易出错.

另一方面,以编程方式定义模式提供了更大的灵活性.例如,如果您使用buildSchema,则仅限于为您的查询和突变传递解析器.如果你只使用默认的解析器对每种类型都没问题,这样可以正常工作 - 但是当你需要为各个字段定义解析器时会发生什么?

以编程方式定义模式允许您为指定的任何类型中的各个字段定义解析器.这不仅有助于转换您从数据库中获取的数据(将其thumbanail_url转换为thumbnailUrl字段),但如果这些字段需要额外的数据库查询,则会阻止它们启动,除非实际请求该字段,这可能是显着的性能提升.正如文档所指出的,如果您想自动生成架构,这种方法也很有用.

就个人而言,这就是我喜欢graphql-tools makeExecutableSchema的原因.这是一种中间方法,允许您以非常干净的方式定义类型(使用GraphQL模式语言),同时允许在实现解析器时具有很大的灵活性.