gpt4 book ai didi

interface - GraphQL 如何避免输入和输出类型之间的重复代码

转载 作者:行者123 更新时间:2023-12-04 11:16:33 24 4
gpt4 key购买 nike

我是 GraphQL 的新手,但我真的很喜欢它。现在我在玩接口(interface)和联合,我面临着突变的问题。

假设我有这个架构:

interface FoodType {
id: String
type: String
composition: [Ingredient]
}

type Pizza implements FoodType {
id: String
type: String
pizzaType: String
toppings: [String]
size: String
composition: [Ingredient]
}

type Salad implements FoodType {
id: String
type: String
vegetarian: Boolean
dressing: Boolean
composition: [Ingredient]
}

type BasicFood implements FoodType {
id: String
type: String
composition: [Ingredient]
}

type Ingredient {
name: String
qty: Float
units: String
}

现在,我想创造新的食物,所以我开始做这样的事情:
type Mutation {
addPizza(input:Pizza):FoodType
addSalad(input:Salad):FoodType
addBasic(input:BasicFood):FoodType
}

这不起作用有两个原因:
  • 如果我想传递一个对象作为参数,这个对象必须是“输入”类型。但是“Pizza”、“Salad”和“BasicFood”只是“类型”。
  • 输入类型不能实现接口(interface)。

  • 所以,我需要像这样修改我以前的架构:
    interface FoodType {
    id: String
    type: String
    composition: [Ingredient]
    }

    type Pizza implements FoodType {
    id: String
    type: String
    pizzaType: String
    toppings: [String]
    size: String
    composition: [Ingredient]
    }

    type Salad implements FoodType {
    id: String
    type: String
    vegetarian: Boolean
    dressing: Boolean
    composition: [Ingredient]
    }

    type BasicFood implements FoodType {
    id: String
    type: String
    composition: [Ingredient]
    }

    type Ingredient {
    name: String
    qty: Float
    units: String
    }

    type Mutation {
    addPizza(input: PizzaInput): FoodType
    addSalad(input: SaladInput): FoodType
    addBasic(input: BasicInput): FoodType
    }

    input PizzaInput {
    type: String
    pizzaType: String
    toppings: [String]
    size: String
    composition: [IngredientInput]
    }

    input SaladInput {
    type: String
    vegetarian: Boolean
    dressing: Boolean
    composition: [IngredientInput]
    }

    input BasicFoodInput {
    type: String
    composition: [IngredientInput]
    }

    input IngredientInput {
    name: String
    qty: Float
    units: String
    }

    所以,在这里我定义了比萨、沙拉和基本食物的 3 种创建方法。
    我需要定义 3 种输入类型(每种食物一种)
    我还需要为成分定义一个新的输入类型。

    它造成了很多重复。那样你觉得可以吗?或者有更好的方法来处理这个问题?

    谢谢

    最佳答案

    你可以做一些事情。例如,如果您要以编程方式声明架构,则可以使用以下方法:

    const getPizzaFields = (isInput = false) => {
    const fields = {
    type: { type: GraphQLString }
    pizzaType: { type: GraphQLString }
    toppings: { type: new GraphQLList(GraphQLString) }
    size: { type: GraphQLString }
    composition: {
    type: isInput ? new GraphQLList(IngredientInput) : new GraphQLList(Ingredient)
    }
    }
    if (!isInput) fields.id = { type: GraphQLString }
    return fields
    }

    const Pizza = new GraphQLObjectType({
    name: 'Pizza',
    fields: () => getFields()
    })

    const PizzaInput = new GraphQLObjectType({
    name: 'Pizza',
    fields: () => getFields(true)
    })

    或者,如果您的对象/输入遵循类似的模式,您甚至可以编写一个函数来从类型生成输入:
    const transformObject = (type) => {
    const input = Object.assign({}, type)
    input.fields.composition.type = new GraphQLList(IngredientInput)
    delete input.fields.id
    return input
    }

    或者,在使用 makeExecutableSchema 定义架构时,你可以这样做:
    const commonPizzaFields = `
    type: String
    pizzaType: String
    toppings: [String]
    size: String
    `

    const schema = `
    type Pizza {
    id: String
    ${commonPizzaFields}
    composition: [Ingredient]
    }

    input PizzaInput {
    ${commonPizzaFields}
    composition: [IngredientInput]
    }
    `

    所有这些方法的问题在于,虽然它们在技术上可能会使您的代码更加 DRY,但它们也会降低您的架构的可读性,在我看来,这使得它比重复本身更容易出错。

    同样重要的是要了解,虽然在语法上,Type 和 Input 类型可能看起来相同,但在功能上却并非如此。例如,类型上的字段可能有参数:
    type Pizza {
    toppings(filter: ToppingTypeEnum): [String]
    }

    输入类型字段没有参数,因此您将无法对 toppings 使用相同的语法。字段中的两个 Pizza类型及其对应物 PizzaInput输入类型。

    就个人而言,我会咬紧牙关,像您已经完成的那样写出类型和输入。我唯一会做的不同是将它们组合在一起(列出您的类型而不是您的输入),以便很容易发现两者之间的任何差异。但你的里程可能会很大:)

    关于interface - GraphQL 如何避免输入和输出类型之间的重复代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48277651/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com