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

时间:2019-09-16 09:12:55

标签: graphql apollo next.js strapi

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

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

GraphQL test

但是,通过将其移植到项目中,它会像这样在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)
    ssrMode: !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 个答案:

答案 0 :(得分:1)

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

PagesFragmentsHome

一切正常。