在 Next.js 应用程序中使用 GraphQL 的推荐方式

Posted

技术标签:

【中文标题】在 Next.js 应用程序中使用 GraphQL 的推荐方式【英文标题】:Recommended way to use GraphQL in Next.js app 【发布时间】:2020-07-06 04:31:59 【问题描述】:

在我的应用程序中,我使用以下 NPM 模块 来玩 Strapi、GraphQL 和 Next.js:

react-apollo next-apollo graphql gql recompose

下一步,我将创建 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);

然后在类组件中,我使用静态方法 getInitialProps() 通过 GraphQL 查询从 Strapi 获取数据。

一切都很好,但也许有另一种更好的方法,通过 React 钩子或任何其他方法?

【问题讨论】:

看看github.com/UnlyEd/next-right-now,它是一个内置 GraphQL 支持的样板,您可能会发现它更容易上手,或者可以将其用作学习资源。有关 GraphQL 查询的用法,请参阅 github.com/UnlyEd/next-right-now/blob/master/src/pages/…。此外,它使用 TypeScript,并在 WebStorm 中内置了 GraphQL 自动完成功能。 还可以查看第一方示例:github.com/zeit/next.js/tree/canary/examples。有几个精简的 graphql 示例(他们的名字中有 graphql) 【参考方案1】:

我发现了另一种使用apollo-server-micro 和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;
    

    通过运行以下命令并检查 graphql URL http://localhost:3000/api/graphql 来测试您的 Next.js 应用 (next-app)

    npm run dev
    

【讨论】:

【参考方案2】:

我为 Next.js 和 GraphQL 找到了一个更好的钩子解决方案。

我想和你分享。让我们开始吧。

注意:我假设您已经安装了 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 访问我们的示例数据和属性 idname

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;

仅此而已..根据需要享受和扩展此解决方案..

【讨论】:

以上是关于在 Next.js 应用程序中使用 GraphQL 的推荐方式的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 NginX + Next.JS + Apollo GraphQL 获取用户的 IP 地址

Apollo Server + Next.js - GraphQL Schema 未更新

如何在没有 useMutation 的情况下在 Next.js 中使用 GraphQL 突变

无法在单个 GraphQL 查询中组合本地和远程数据(Next.js + Apollo)

如何在 Next.js 代码优先方法中使用 graphql-type-json 标量

使用 GraphQL 变量和 Next JS 过滤数组中的数据