【问题标题】:Declarative vs Programmatically GraphQL声明式 vs 编程式 GraphQL
【发布时间】:2018-01-05 12:16:57
【问题描述】:

我正在为新的全栈项目采用 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 应用程序,因此架构会变得非常复杂,我担心代码很快就会变得复杂。

那么,我应该采用声明式方法、程序式方法还是两者的混合?

这里的最佳做法是什么?

【问题讨论】:

    标签: javascript graphql


    【解决方案1】:

    关于这个话题herehere 有很多讨论。

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

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-16
        • 2011-05-01
        • 2023-04-01
        • 2012-01-02
        • 1970-01-01
        • 2010-12-09
        相关资源
        最近更新 更多