声明式与编程式GraphQL

时间:2017-07-29 14:13:15

标签: javascript graphql

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

我的问题与使用声明性和编程式GraphQL架构定义有关。基本上我在GraphQL official site中可以看到的只使用声明性方法:在一个或多个文件中定义模式,如(感谢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]
}

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

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

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
}

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

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

这里的最佳做法是什么?

2 个答案:

答案 0 :(得分:5)

关于此主题的herehere进行了大量讨论。

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

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

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

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

答案 1 :(得分:0)

您可以使用merge-graphql-schemas库来更好地进行架构设计。 这个post演示了如何模块化graphql模式,使用库并提供可以克隆的种子项目。希望能帮助到你! :)

相关问题