在 Next.js 应用中使用 GraphQL 的推荐方式
Recommended way to use GraphQL in Next.js app
在我的应用程序中,我使用以下 NPM 模块 来玩 Strapi, GraphQL and Next.js:
下一步,我将创建 Apollo 配置文件,示例如下:
import { HttpLink } from "apollo-link-http";
import { withData } from "next-apollo";
const config = {
link: new HttpLink({
uri: "http://localhost:1337/graphql",
})
};
export default withData(config);
然后在 class 组件内,我使用静态方法 getInitialProps()
通过 GraphQL 查询从 Strapi 获取数据。
一切都很好,但也许还有另一种更好的方法,通过 React hooks 或任何其他方法?
我找到了一个更有趣的解决方案,使用 apollo-server-micro and lodash
快速指南:
创建 Next.js 应用程序(示例名称:next-app)并安装所需的包
npm i apollo-server-micro lodash
在您的 Next.js 应用中创建所需的文件 (next-app)
- /next-app/pages/api/graphql/index.js
- /next-app/pages/api/graphql/resolvers.js
- /next-app/pages/api/graphql/typeDefs.js
添加代码到index.js
import { ApolloServer } from 'apollo-server-micro';
import resolvers from './resolvers';
import typeDefs from './TypeDef';
const apolloServer = new ApolloServer({
typeDefs,
resolvers,
});
export const config = {
api: {
bodyParser: false
}
};
export default apolloServer.createHandler({ path: '/api/graphql' });
添加代码到typeDefs.js
import { gql } from 'apollo-server-micro';
const typeDefs = gql`
type User {
id: Int!
name: String!
age: Int
active: Boolean!
}
type Query {
getUser(id: Int): User
}
`;
export default typeDefs;
添加代码到resolvers.js
import lodash from 'lodash/collection';
const users = [
{ id: 1, name: 'Mario', age: 38, active: true },
{ id: 2, name: 'Luigi', age: 40, active: true},
{ id: 3, name: 'Wario', age: 36, active: false }
];
const resolvers = {
Query: {
getUser: (_, { id }) => {
return lodash.find(users, { id });
}
}
};
export default resolvers;
通过以下命令 运行 测试您的 Next.js 应用程序 (next-app) 并检查 graphql URL http://localhost:3000/api/graphql
npm run dev
我为 Next.js 和 GraphQL 找到了一个更好的 hook 解决方案。
我想和你分享。开始吧。
注意: 我假设您已经安装了 Next.js 应用程序。如果不是,请按照此 guide.
要构建此解决方案,我们需要:
- @apollo/react-hooks
- apollo-cache-inmemory
- apollo-client
- apollo-link-http
- graphql
- graphql-tag
- isomorphic-unfetch
- next-with-apollo
1. 运行 npm 命令:
npm install --save @apollo/react-hooks apollo-cache-inmemory apollo-client apollo-link-http graphql graphql-tag isomorphic-unfetch next-with-apollo
2. 创建 Appolo 配置文件,例如。在文件夹 ./config
中并将其命名为 appollo.js
。文件代码如下:
import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import withApollo from "next-with-apollo";
import { createHttpLink } from "apollo-link-http";
import fetch from "isomorphic-unfetch";
const GRAPHQL_URL = process.env.BACKEND_URL || "https://api.graphql.url";
const link = createHttpLink({
fetch,
uri: GRAPHQL_URL
});
export default withApollo(
({ initialState }) =>
new ApolloClient({
link: link,
cache: new InMemoryCache()
.restore(initialState || {})
})
);
3. 使用以下代码在 ./pages
文件夹中创建 _app.js
文件(一种包装器):
import React from "react";
import Head from "next/head";
import { ApolloProvider } from "@apollo/react-hooks";
import withData from "../config/apollo";
const App = ({ Component, pageProps, apollo }) => {
return (
<ApolloProvider client={apollo}>
<Head>
<title>App Title</title>
</Head>
<Component {...pageProps} />
</ApolloProvider>
)
};
export default withData(App);
4. 创建可重用的查询组件,例如。 ./components/query.js
import React from "react";
import { useQuery } from "@apollo/react-hooks";
const Query = ({ children, query, id }) => {
const { data, loading, error } = useQuery(query, {
variables: { id: id }
});
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {JSON.stringify(error)}</p>;
return children({ data });
};
export default Query;
5. 为我们通过 GraphQL 获取的数据创建一个组件
import React from "react";
import Query from "../components/query";
import GRAPHQL_TEST_QUERY from "../queries/test-query";
const Example = () => {
return (
<div>
<Query query={GRAPHQL_TEST_QUERY} id={null}>
{({ data: { graphqlData } }) => {
return (
<div>
{graphqlData.map((fetchedItem, i) => {
return (
<div key={fetchedItem.id}>
{fetchedItem.name}
</div>
);
})}
</div>
);
}}
</Query>
</div>
);
};
export default Example;
6. 在 ./queries/test-query
中创建我们的 GraphQL 查询。 注意: 我假设我们可以通过 GraphQL
访问示例数据和属性 id
和 name
import gql from "graphql-tag";
const GRAPHQL_TEST_QUERY = gql`
query graphQLData {
exampleTypeOfData {
id
name
}
}
`;
export default GRAPHQL_TEST_QUERY;
7. 显示我们的结果使用以下代码在 ./pages
文件夹中创建 index.js
文件(主页):
import Example from './components/example';
const Index = () => <div><Example /></div>
export default Index;
就是这样..随心所欲地享受和扩展这个解决方案..
在我的应用程序中,我使用以下 NPM 模块 来玩 Strapi, GraphQL and Next.js:
下一步,我将创建 Apollo 配置文件,示例如下:
import { HttpLink } from "apollo-link-http";
import { withData } from "next-apollo";
const config = {
link: new HttpLink({
uri: "http://localhost:1337/graphql",
})
};
export default withData(config);
然后在 class 组件内,我使用静态方法 getInitialProps()
通过 GraphQL 查询从 Strapi 获取数据。
一切都很好,但也许还有另一种更好的方法,通过 React hooks 或任何其他方法?
我找到了一个更有趣的解决方案,使用 apollo-server-micro and lodash
快速指南:
创建 Next.js 应用程序(示例名称:next-app)并安装所需的包
npm i apollo-server-micro lodash
在您的 Next.js 应用中创建所需的文件 (next-app)
- /next-app/pages/api/graphql/index.js
- /next-app/pages/api/graphql/resolvers.js
- /next-app/pages/api/graphql/typeDefs.js
添加代码到index.js
import { ApolloServer } from 'apollo-server-micro'; import resolvers from './resolvers'; import typeDefs from './TypeDef'; const apolloServer = new ApolloServer({ typeDefs, resolvers, }); export const config = { api: { bodyParser: false } }; export default apolloServer.createHandler({ path: '/api/graphql' });
添加代码到typeDefs.js
import { gql } from 'apollo-server-micro'; const typeDefs = gql` type User { id: Int! name: String! age: Int active: Boolean! } type Query { getUser(id: Int): User } `; export default typeDefs;
添加代码到resolvers.js
import lodash from 'lodash/collection'; const users = [ { id: 1, name: 'Mario', age: 38, active: true }, { id: 2, name: 'Luigi', age: 40, active: true}, { id: 3, name: 'Wario', age: 36, active: false } ]; const resolvers = { Query: { getUser: (_, { id }) => { return lodash.find(users, { id }); } } }; export default resolvers;
通过以下命令 运行 测试您的 Next.js 应用程序 (next-app) 并检查 graphql URL http://localhost:3000/api/graphql
npm run dev
我为 Next.js 和 GraphQL 找到了一个更好的 hook 解决方案。
我想和你分享。开始吧。
注意: 我假设您已经安装了 Next.js 应用程序。如果不是,请按照此 guide.
要构建此解决方案,我们需要:
- @apollo/react-hooks
- apollo-cache-inmemory
- apollo-client
- apollo-link-http
- graphql
- graphql-tag
- isomorphic-unfetch
- next-with-apollo
1. 运行 npm 命令:
npm install --save @apollo/react-hooks apollo-cache-inmemory apollo-client apollo-link-http graphql graphql-tag isomorphic-unfetch next-with-apollo
2. 创建 Appolo 配置文件,例如。在文件夹 ./config
中并将其命名为 appollo.js
。文件代码如下:
import { ApolloClient } from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import withApollo from "next-with-apollo";
import { createHttpLink } from "apollo-link-http";
import fetch from "isomorphic-unfetch";
const GRAPHQL_URL = process.env.BACKEND_URL || "https://api.graphql.url";
const link = createHttpLink({
fetch,
uri: GRAPHQL_URL
});
export default withApollo(
({ initialState }) =>
new ApolloClient({
link: link,
cache: new InMemoryCache()
.restore(initialState || {})
})
);
3. 使用以下代码在 ./pages
文件夹中创建 _app.js
文件(一种包装器):
import React from "react";
import Head from "next/head";
import { ApolloProvider } from "@apollo/react-hooks";
import withData from "../config/apollo";
const App = ({ Component, pageProps, apollo }) => {
return (
<ApolloProvider client={apollo}>
<Head>
<title>App Title</title>
</Head>
<Component {...pageProps} />
</ApolloProvider>
)
};
export default withData(App);
4. 创建可重用的查询组件,例如。 ./components/query.js
import React from "react";
import { useQuery } from "@apollo/react-hooks";
const Query = ({ children, query, id }) => {
const { data, loading, error } = useQuery(query, {
variables: { id: id }
});
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {JSON.stringify(error)}</p>;
return children({ data });
};
export default Query;
5. 为我们通过 GraphQL 获取的数据创建一个组件
import React from "react";
import Query from "../components/query";
import GRAPHQL_TEST_QUERY from "../queries/test-query";
const Example = () => {
return (
<div>
<Query query={GRAPHQL_TEST_QUERY} id={null}>
{({ data: { graphqlData } }) => {
return (
<div>
{graphqlData.map((fetchedItem, i) => {
return (
<div key={fetchedItem.id}>
{fetchedItem.name}
</div>
);
})}
</div>
);
}}
</Query>
</div>
);
};
export default Example;
6. 在 ./queries/test-query
中创建我们的 GraphQL 查询。 注意: 我假设我们可以通过 GraphQL
id
和 name
import gql from "graphql-tag";
const GRAPHQL_TEST_QUERY = gql`
query graphQLData {
exampleTypeOfData {
id
name
}
}
`;
export default GRAPHQL_TEST_QUERY;
7. 显示我们的结果使用以下代码在 ./pages
文件夹中创建 index.js
文件(主页):
import Example from './components/example';
const Index = () => <div><Example /></div>
export default Index;
就是这样..随心所欲地享受和扩展这个解决方案..