【问题标题】:How to implement a reference type on a ObjectType that comes from a class in GraphQL pothos (Next JS)如何在来自 GraphQL pothos (Next JS) 中的类的 ObjectType 上实现引用类型
【发布时间】:2022-10-23 20:39:13
【问题描述】:

我正在尝试参考输入我的大车键入我尝试了几种不同的方法并不断收到此错误:

:Ref function String() { [native code] } 尚未实现

在我的项目中,我将我的类型作为文档中推荐的类导入,

我的类型:

这与我的服务器位于单独的文件中

export class CartItem {
    id: string;
    name: string;
    price: number;
    quantity: number;

    constructor(id: string, name: string, price: number, quantity: number) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.quantity = quantity;
    }
}
export class Cart {
    id: string;
    items?: CartItem[];

    constructor(id: string, items?: CartItem[]) {
        this.id = id;
        this.items = items;
    }
}
export class Money {
    amount: number;
    formatted: string;

    constructor(amount: number, formatted: string) {
        this.amount = amount;
        this.formatted = formatted;

    }
}

这是我的服务器:

我有两个 cmets 显示我可能失败的地方

  1. 在我的购物车中
  2. 常量 MoneyType
    import { createServer } from '@graphql-yoga/node'
    import SchemaBuilder from "@pothos/core"
    import { CartItem, Cart, Money } from 'gql';
    
    
    const CARTS = [
        {
            id: '1',
            items: [
                {
                    id: '1',
                    name: 'Item 1',
                    price: 10,
                    quantity: 1
                },
                {
                    id: '2',
                    name: 'Item 2',
                    price: 20,
                    quantity: 2
                }
            ]
        },
        {
            id: '2',
            items: [
                {
                    id: '3',
                    name: 'Item 3',
                    price: 30,
                    quantity: 3
                },
                {
                    id: '4',
                    name: 'Item 4',
                    price: 40,
                    quantity: 4
                }
            ]
        }
    ]
    
    
    
    const builder = new SchemaBuilder({});
    
    builder.objectType(Cart, {
        name: "Cart",
        description: "A cart",
        fields: (t) => ({
            id: t.exposeString('id', {}),
            items: t.field({
                type: [CartItem],
                resolve: (cart) => cart.items ?? [],
            }),
    
            // This is the field that we want to USE TO REFERENCE
            // subTotal: t.field({
                //     type: Money,
                //     resolve: (cart) => {
                    //         const total = cart.items?.reduce((acc, item) => acc + item.price * item.quantity, 0) ?? 0;
                    //         return new Money(total, `$${total}`);
                    //     }
                    // })
                }),
            });
            
            builder.objectType(CartItem, {
                name: "CartItem",
                description: "A cart item",
                fields: (t) => ({
                    id: t.exposeString('id', {}),
                    name: t.exposeString('name', {}),
                    price: t.exposeInt('price', {}),
                    quantity: t.exposeInt('quantity', {}),
                }),
            });
            
            // make a reference to the Money type THAT DOESEN'T WORK
            const MoneyType = builder.objectRef<MoneyShape>("Money");
    
            
            builder.objectType(Money, {
                name: "Money",
                description: "A money",
                fields: (t) => ({
                    amount: t.exposeInt('amount', {}),
                    formatted: t.field({
                        type: String,
                        resolve: (money) => new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(money.amount),
                    }),
                }),
            });
            
            
            builder.queryType({
                fields: (t) => ({
            cart: t.field({
                type: Cart,
                nullable: true,
                args: {
                    id: t.arg.id({ required: true, description: "the id of the cart" }),
                },
                resolve: (_, { id }) => {
                    const cart = CARTS.find((cart) => cart.id === id);
    
                    if (!cart) {
                        throw new Error(`Cart with id ${id} not found`)
                    }
    
                    return cart
                }
            }),
            carts: t.field({
                type: [Cart],
                resolve: () => CARTS
            }),
        }),
    })
    
    
    
    
    
    const server = createServer({
        endpoint: '/api',
        schema: builder.toSchema(),
    })
    
    
    export default server;
    

【问题讨论】:

    标签: graphql apollo-server typegraphql


    【解决方案1】:

    不幸的是,Pothos 的错误消息在 type 属性方面并不是很好。 Pothos 中的标量由它们的名称引用,因此您应该将它们放在引号中:

    builder.objectType(Money, {
      name: "Money",
      description: "A money",
      fields: (t) => ({
        amount: t.exposeInt("amount", {}),
        formatted: t.field({
          type: "String",
          resolve: (money) =>
            new Intl.NumberFormat("en-US", {
              style: "currency",
              currency: "USD",
            }).format(money.amount),
        }),
      }),
    });
    

    或者,您也可以使用t.string

    builder.objectType(Money, {
      name: "Money",
      description: "A money",
      fields: (t) => ({
        amount: t.exposeInt("amount", {}),
        formatted: t.string({
          resolve: (money) =>
            new Intl.NumberFormat("en-US", {
              style: "currency",
              currency: "USD",
            }).format(money.amount),
        }),
      }),
    });
    

    一些额外的提示:

    我会将格式化程序移出解析器,因为您只需创建一个实例。

    我个人不喜欢 Pothos 的上课方式,因为我的类型大多来自 Prisma。如果您对每种对象类型都有服务类,它的效果非常好,但是如果您只是让它们来包装东西,那么开销会很大。您可以考虑删除 Money 类并改用 number :

    const moneyFormatter = new Intl.NumberFormat("en-US", {
      style: "currency",
      currency: "USD",
    })
    
    const Money = builder.objectRef<number>('Money').implement({
      description: "A money",
      fields: (t) => ({
        amount: t.int({ resolve: money => money }),
        formatted: t.string({
          resolve: (money) =>
            moneyFormatter.format(money),
        }),
      }),
    });
    

    【讨论】:

      猜你喜欢
      • 2021-08-31
      • 2021-03-22
      • 2019-04-10
      • 1970-01-01
      • 2020-12-22
      • 2018-04-15
      • 2023-03-08
      • 1970-01-01
      • 2021-03-06
      相关资源
      最近更新 更多