将 GraphQL 片段与 Apollo Hooks 一起使用时出错
Error using GraphQL Fragments with Apollo Hooks
我正在开发一个 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)
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
产生错误的原因是什么?
这是我使用这些技术的第一个项目,所以我可能遗漏了一些东西。
在此先感谢您的帮助。
问题已解决。这是由 PagesFragmentHome
片段声明中的一个愚蠢的语法错误引起的。将其替换为:
PagesFragmentsHome
一切正常。
我正在开发一个 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)
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
产生错误的原因是什么? 这是我使用这些技术的第一个项目,所以我可能遗漏了一些东西。
在此先感谢您的帮助。
问题已解决。这是由 PagesFragmentHome
片段声明中的一个愚蠢的语法错误引起的。将其替换为:
PagesFragmentsHome
一切正常。