今天我們將導入graphql,我們這次使用的是Apollo Client 3,Apollo Client是一個完整的GraphQL管理數據的解決方案,它使開發人員可以輕鬆地從伺服器查詢數據,然後將數據存儲在本地。
我們可以先看一下是如何用做的:(圖片來源: Link)
接下來我們安裝相關套件:
pnpm add @apollo/client graphql @apollo/experimental-nextjs-app-support
pnpm add -D @graphql-codegen/cli @graphql-codegen/typescript-react-apollo @graphql-codegen/typescript-operations @faker-js/faker
我們要在我們Nextjs 13加入Apollo client,具體方式可以參考該篇文章Link。我們將ApolloNextAppProvider
加入到我們的provider。打開apps\iron-ecommerce-next\app\app-provider.tsx
:
"use client";
import { ApolloLink, HttpLink } from "@apollo/client";
import {
ApolloNextAppProvider,
NextSSRApolloClient,
NextSSRInMemoryCache,
SSRMultipartLink,
} from "@apollo/experimental-nextjs-app-support/ssr";
import { CSSProvider } from "@master/css.react";
import { Theme } from "@radix-ui/themes";
import config from "master.css";
import { RecoilRoot } from "recoil";
// see: https://www.apollographql.com/blog/announcement/frontend/using-apollo-client-with-next-js-13-releasing-an-official-library-to-support-the-app-router/
const makeGraphqlClient = () => {
const httpLink = new HttpLink({
uri: 'http://localhost:3300/graphql',
})
return new NextSSRApolloClient({
cache: new NextSSRInMemoryCache(),
link:
typeof window === 'undefined'
? ApolloLink.from([
new SSRMultipartLink({
stripDefer: true,
}),
httpLink,
])
: httpLink,
})
}
export default function AppProvider({ children }: { children: React.ReactNode }) {
return (
<ApolloNextAppProvider makeClient={makeGraphqlClient}>
<RecoilRoot>
<Theme>
<CSSProvider config={config}>{children}</CSSProvider>
</Theme>
</RecoilRoot>
</ApolloNextAppProvider>
);
}
接下來先創建一個簡易的schema。apps\iron-ecommerce-next\libs\graphql\schema.graphql
:
scalar DateTime
type Product {
id: ID!
name: String!
price: Float!
description: String!
imageUrl: String!
}
type CartItem {
productId: ID!
productName: String!
price: Float!
quantity: Int!
}
type User {
id: ID!
name: String!
email: String!
}
type AuthPayload {
user: User!
token: String!
}
input UserInput {
name: String!
email: String!
password: String!
}
input CartItemInput {
productId: ID!
quantity: Int!
}
type Order {
id: ID!
items: [CartItem!]!
orderDate: DateTime!
}
type Query {
getProducts: [Product!]!
getProduct(id: ID!): Product
getUserProfile: User
getCartItems: [CartItem!]!
}
type Mutation {
loginUser(username: String!, password: String!): AuthPayload
registerUser(input: UserInput!): AuthPayload
addCartItem(productId: ID!, quantity: Int!): [CartItem!]!
removeCartItem(productId: ID!): [CartItem!]!
updateCartItem(productId: ID!, quantity: Int!): [CartItem!]!
checkout(cartItems: [CartItemInput!]!): Order
}
接下來創建codegen,apps\iron-ecommerce-next\libs\graphql\codegen.ts
:
import { CodegenConfig } from "@graphql-codegen/cli";
const config: CodegenConfig = {
overwrite: true,
schema: "apps/iron-ecommerce-next/libs/graphql/schema.graphql",
documents: ["apps/iron-ecommerce-next/**/*.ts", "apps/iron-ecommerce-next/**/*.tsx"],
ignoreNoDocuments: true,
generates: {
"apps/iron-ecommerce-next/__generated__/generated-hooks.ts": {
plugins: ["typescript", "typescript-operations", "typescript-react-apollo"],
config: {
skipTypename: false,
withHooks: true,
withHOC: false,
withComponent: false,
apolloReactHooksImportFrom: "@apollo/client"
},
presetConfig: {
gqlTagName: "gql",
fragmentMasking: false,
futureProofEnums: true
}
}
}
};
export default config;
接下來我們加入run command到我們的Nextjs裡,打開apps\iron-ecommerce-next\project.json
創建graphql-generate
"graphql-generate": {
"executor": "nx:run-commands",
"options": {
"command": "graphql-codegen --config apps/iron-ecommerce-next/libs/graphql/codegen.ts"
}
}
},
"tags": []
}
然後我們試著執行指令:pnpm exec nx run iron-ecommerce-next:graphql-generate
接著我們可以看到codegen幫我們創建出apps\iron-ecommerce-next\__generated__\generated-hooks.ts
本文介紹了如何在Next.js中導入和設置Apollo Client 3。並通過使用Codegen工具,來自動生成所需的GraphQL查詢和變更的hook。最後使用Nx提供的run commands來執行我們得Codegen,下一章將會試著使用graphql資料,不過由於我們沒有server,所以會先使用mock方式來創建假資料。