You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何替换Postgraphile中自动生成的foo API端点?

解决Postgraphile中恢复foo { title }查询格式的问题

核心问题原因

你之前使用makeExtendSchemaPlugin时直接重新定义了type Foo,和Postgraphile自动生成的Foo类型冲突,导致重复定义错误。正确的做法是扩展已有类型而非重新定义,或按需移除自动生成的字段/类型后再自定义。


推荐方案:扩展Foo类型添加title字段

直接为Postgraphile自动生成的Foo GraphQL类型扩展title字段,解析时关联到关联的Bar的title,无需替换整个端点,代码简洁且避免N+1查询问题:

const { makeExtendSchemaPlugin, gql } = require('postgraphile');

const fooTitleExtensionPlugin = makeExtendSchemaPlugin((build) => ({
  typeDefs: gql`
    // 扩展已有的Foo类型,添加title字段
    extend type Foo {
      title: String!
    }
  `,
  resolvers: {
    Foo: {
      // 利用Postgraphile自动生成的bar关联字段获取title
      async title(foo) {
        const bar = await foo.bar;
        return bar.title;
      },
    },
  },
}));

将该插件添加到Postgraphile的启动配置中(比如通过--plugins参数或代码配置的plugins数组),之后就能直接用foo { title }查询,和原来的API格式完全一致。


进阶方案:移除自动生成内容后自定义

如果需要完全替换自动生成的Foo类型或Query中的foo端点,可以先移除自动生成的内容,再自定义:

1. 移除自动生成的Foo类型

const { makeRemoveTypePlugin } = require('postgraphile');
const removeAutoFooType = makeRemoveTypePlugin('Foo');

2. 自定义Foo类型及查询端点

const { makeExtendSchemaPlugin, gql } = require('postgraphile');

const customFooSchemaPlugin = makeExtendSchemaPlugin(() => ({
  typeDefs: gql`
    type Foo {
      id: Int!
      barId: Int!
      title: String!
      bar: Bar!
    }

    extend type Query {
      foo(id: Int!): Foo
      foos: [Foo!]!
    }
  `,
  resolvers: {
    Foo: {
      async title(foo, _, context) {
        // 直接查询数据库获取对应Bar的title
        const { rows } = await context.pg.query(
          'SELECT title FROM bars WHERE id = $1',
          [foo.barId]
        );
        return rows[0].title;
      },
      async bar(foo, _, context) {
        const { rows } = await context.pg.query(
          'SELECT * FROM bars WHERE id = $1',
          [foo.barId]
        );
        return rows[0];
      },
    },
    Query: {
      async foo(_, { id }, context) {
        const { rows } = await context.pg.query(
          'SELECT * FROM foos WHERE id = $1',
          [id]
        );
        return rows[0];
      },
      async foos(_, __, context) {
        const { rows } = await context.pg.query('SELECT * FROM foos');
        return rows;
      },
    },
  },
}));

3. 加载插件顺序

启动Postgraphile时需先加载移除插件,再加载自定义插件,确保自动生成的类型被移除后再创建自定义类型:

// 代码配置示例
postgraphile(pgConfig, schemaName, {
  plugins: [removeAutoFooType, customFooSchemaPlugin],
  // 其他配置...
});

内容的提问来源于stack exchange,提问作者machineghost

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 23:11:35