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

NextJS+Apollo+GraphQL使用Fragment触发500错误求助

解决Apollo复用GraphQL Fragment时出现500错误的问题

我尝试在GraphQL查询中复用基础Fragment,通过${NEXT_SEO_FRAGMENT}变量插入时触发ApolloError,提示Response not successful: Received status code 500。直接写字段的查询可正常运行,但使用Fragment就报错。

报错代码

import { getApolloClient } from "../apollo-client";
import gql from 'graphql-tag'

import { Locale } from "../types";

const NEXT_SEO_FRAGMENT = gql`
  fragment NextSeoFields on NextSeoType {
    seoDescription
    seoTitle
  }
`;

export async function getHomeEntrys(locale: Locale) {
  const apolloClient = getApolloClient();

  const language = locale;
  const { data } = await apolloClient.query({
    query: gql`
      query pages($language: LanguageCodeFilterEnum!) {
        pages(where: { language: $language }) {
          edges {
            node {
              title
              content
              slug
              language {
                code
                locale
              }
              id
              isFrontPage
              nextSeo {
                ...NextSeoFields
              }
            }
          }
        }
      }
      ${NEXT_SEO_FRAGMENT}
    `,
    variables: {
        language,
      },
  });
  return data?.pages.edges
}

正常运行的代码(未使用Fragment)

import { getApolloClient } from "../apollo-client";
import gql from 'graphql-tag'

import { Locale } from "../types";

export async function getHomeEntrys(locale: Locale) {
  const apolloClient = getApolloClient();

  const language = locale;
  const { data } = await apolloClient.query({
    query: gql`
      query pages($language: LanguageCodeFilterEnum!) {
        pages(where: { language: $language }) {
          edges {
            node {
              title
              content
              slug
              language {
                code
                locale
              }
              id
              isFrontPage
              nextSeo {
                seoDescription
                seoTitle
              }
            }
          }
        }
      }
    `,
    variables: {
        language,
      },
  });
  return data?.pages.edges
}

问题原因

gql标签返回的是解析后的GraphQL AST(DocumentNode对象),而非字符串。直接在模板字符串中用${NEXT_SEO_FRAGMENT}插入该对象时,会被强制转换为[object Object],导致最终的查询语法完全错误,服务器因此返回500状态码。

解决方案

方案1:将Fragment与查询放在同一个gql模板中

把Fragment定义直接写在查询语句的同一gql标签内,确保AST被正确解析:

import { getApolloClient } from "../apollo-client";
import gql from 'graphql-tag'
import { Locale } from "../types";

export async function getHomeEntrys(locale: Locale) {
  const apolloClient = getApolloClient();
  const language = locale;
  const { data } = await apolloClient.query({
    query: gql`
      fragment NextSeoFields on NextSeoType {
        seoDescription
        seoTitle
      }
      
      query pages($language: LanguageCodeFilterEnum!) {
        pages(where: { language: $language }) {
          edges {
            node {
              title
              content
              slug
              language {
                code
                locale
              }
              id
              isFrontPage
              nextSeo {
                ...NextSeoFields
              }
            }
          }
        }
      }
    `,
    variables: { language },
  });
  return data?.pages.edges
}

方案2:用gql标签合并独立Fragment与查询

如果需要单独定义Fragment以复用,可通过gql标签直接插入的方式合并AST:

import { getApolloClient } from "../apollo-client";
import gql from 'graphql-tag'
import { Locale } from "../types";

const NEXT_SEO_FRAGMENT = gql`
  fragment NextSeoFields on NextSeoType {
    seoDescription
    seoTitle
  }
`;

export async function getHomeEntrys(locale: Locale) {
  const apolloClient = getApolloClient();
  const language = locale;
  const { data } = await apolloClient.query({
    query: gql`
      ${NEXT_SEO_FRAGMENT}
      
      query pages($language: LanguageCodeFilterEnum!) {
        pages(where: { language: $language }) {
          edges {
            node {
              title
              content
              slug
              language {
                code
                locale
              }
              id
              isFrontPage
              nextSeo {
                ...NextSeoFields
              }
            }
          }
        }
      }
    `,
    variables: { language },
  });
  return data?.pages.edges
}

注意:部分GraphQL服务器要求Fragment定义必须出现在查询语句之前,因此建议将Fragment放在查询上方。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 04:57:49