将 GraphQL 片段与 Apollo Hooks 一起使用时出错

Posted

技术标签:

【中文标题】将 GraphQL 片段与 Apollo Hooks 一起使用时出错【英文标题】:Error using GraphQL Fragments with Apollo Hooks 【发布时间】:2020-01-17 02:29:26 【问题描述】:

我正在开发一个 NextJS 项目,使用 Strapi 作为 CMS,使用 GraphQL 插件和 Apollo 作为GraphQL 客户端。我的问题与 Apollo Hooks 有关。我正在尝试将查询片段与新的useQuery 挂钩使用,但没有成功。

在 GraphQL 操场上测试我的查询,一切正常 - 数据正确返回,如下所示:

但是,通过将这个移植到项目中,它会在 Apollo 客户端中生成一个500 network error,如下所示:

Error while running `getDataFromTree`  Error: Network error: Response not successful: Received status code 500
    at new ApolloError (/Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-client/bundle.umd.js:92:26)
    at /Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-client/bundle.umd.js:1587:34
    at /Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-client/bundle.umd.js:2007:15
    at Set.forEach (<anonymous>)
    at /Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-client/bundle.umd.js:2005:26
    at Map.forEach (<anonymous>)
    at QueryManager.broadcastQueries (/Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-client/bundle.umd.js:2003:20)
    at /Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-client/bundle.umd.js:1482:29
    at process._tickCallback (internal/process/next_tick.js:68:7)
  graphQLErrors: [],
  networkError:
    ServerError: Response not successful: Received status code 500
       at Object.exports.throwServerError (/Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-link-http-common/lib/index.js:23:17)
       at /Users/lucacattide/Vagrant/debian/public/LC/front-end/node_modules/apollo-link-http-common/lib/index.js:48:21
       at process._tickCallback (internal/process/next_tick.js:68:7)
     name: 'ServerError',
     response:
      Response 
        size: 0,
        timeout: 0,
        [Symbol(Body internals)]: [Object],
        [Symbol(Response internals)]: [Object] ,
     statusCode: 500,
     result:  errors: [Array]  ,
  message:
   'Network error: Response not successful: Received status code 500',
  extraInfo: undefined 

这是我的实现:

阿波罗

// Module Start
// Apollo Client
// JS imports
import 
  ApolloClient
 from 'apollo-client';
import 
  InMemoryCache
 from 'apollo-cache-inmemory';
import 
  HttpLink
 from 'apollo-link-http';
import 
  onError
 from 'apollo-link-error';
import 
  ApolloLink
 from 'apollo-link';
import fetch from 'isomorphic-unfetch';

let apolloClient = null;

/**
 * @description Client definition
 * @author Luca Cattide
 * @date 2019-06-27
 * @param * initialState
 * @return object
 */
function create(initialState) 
  const isBrowser = typeof window !== 'undefined';

  // Check out https://github.com/zeit/next.js/pull/4611 if you want to use the AWSAppSyncClient
  return new ApolloClient(
    connectToDevTools: isBrowser,
    // Disables forceFetch on the server (so queries are only run once)
    s-s-rMode: !isBrowser,
    link: ApolloLink.from([
      onError((
        graphQLErrors,
        networkError
      ) => 
        if (graphQLErrors)
          graphQLErrors.forEach((
              message,
              locations,
              path
            ) =>
            console.log(
              `[GraphQL error]: Message: $message, Location: $locations, Path: $path`,
            ),
          );
        if (networkError) console.log(`[Network error]: $networkError`);
      ),
      new HttpLink(
        // Server URL (must be absolute) - Es. https://api.graph.cool/simple/v1/cixmkt2ul01q00122mksg82pn
        // TODO: Change to proper url in production
        uri: 'http://localhost:1337/graphql',
        // Additional fetch() options like `credentials` or `headers`
        credentials: 'same-origin',
        // Use fetch() polyfill on the server
        fetch: !isBrowser && fetch
      )
    ]),
    cache: new InMemoryCache().restore(initialState || ),
  );


/**
 * @description Client initialization
 * @author Luca Cattide
 * @date 2019-06-27
 * @export
 * @param * initialState
 * @return object
 */
export default function initApollo(initialState) 
  // Make sure to create a new client for every server-side request so that data
  // isn't shared between connections (which would be bad)
  if (typeof window === 'undefined') 
    return create(initialState);
  

  // Reuse client on the client-side
  if (!apolloClient) 
    apolloClient = create(initialState);
  

  return apolloClient;

// Module End

查询

// Module Start
// JS imports
import gql from 'graphql-tag';
import Pages from './fragments/pages';

// Queries
// Page
const PAGE_QUERY = gql`
  query Pages($where: JSON, $isHome: Boolean!) 
    pages(where: $where) 
      ...PagesFragmentsPage
      ...PagesFragmentsHome @include(if: $isHome)
    
  

  $Pages.fragments.page
  $Pages.fragments.home
`;

// Module export
export default PAGE_QUERY;
// Module end

片段

// Module Start
// JS imports
import gql from 'graphql-tag';

// Fragments
const Pages = ;

// Pages
Pages.fragments = 
  page: gql`
    fragment PagesFragmentsPage on Page 
      id
      name_en
      keywords_en
      description_en
    
  `,
  home: gql`
    fragment PagesFragmentHome on Page 
      headline_en
      cta_en
      cta_two_en
      cta_three_en
      cta_four_en
      cta_five_en
      summary_title_en
      summary_en
      headline_two_en
      headline_three_en
      headline_four_en
      headline_five_en
      section_title_en
      indicators 
        id
        value
        label_en
      
      testimonials 
        id
        name
        quote_en
      
    
  `,
;

// Module export
export default Pages;
// Module End

NextJS 页面

// Module Start
// Home
// Various imports...
// JS imports
import dynamic from 'next/dynamic'
import useQuery from '@apollo/react-hooks'
import PAGE_QUERY from '../backend/queries/pages'

const ErrorDb = dynamic(() =>
  import('../components/ErrorDb')
)
// Main
const Index = (origin, pathname) => 
  const loading, error, data = useQuery(PAGE_QUERY, 
    variables: 
      where: 
        name_en: 'Home'
      ,
      isHome: true
    
  );
  const pages = data;

  // Exception check
  if (error) 
    return <ErrorDb />
  
  // DB fetching check
  if (loading) 
    return null;
  

  return (
    <>
      // Implementation...
    </>
  );


// Module export
export default Index
// Module End

产生错误的原因是什么? 这是我使用这些技术的第一个项目,所以我可能遗漏了一些东西。

提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

问题已解决。这是由PagesFragmentHome 片段声明中的愚蠢语法错误引起的。通过将其替换为:

PagesFragmentsHome

一切正常。

【讨论】:

以上是关于将 GraphQL 片段与 Apollo Hooks 一起使用时出错的主要内容,如果未能解决你的问题,请参考以下文章

能够使用相同的字段扩展所有 Apollo/GraphQL 突变。通缉“通用片段”

从 TypeScript 类型定义或 GraphQL 片段定义生成 JavaScript 空对象

GraphQL 片段的片段

为啥将 Apollo 与 Nuxt 一起使用需要 graphql-tag?

将 offsetLimitPagination 与过滤 Apollo Graphql 相结合

如何将 redux 与 graphql 一起使用