iT邦幫忙

2023 iThome 鐵人賽

DAY 15
0
Modern Web

由前向後,從前端邁向全端系列 第 15

15.【從前端到全端,Nextjs+Nestjs】在Nextjs 13設置並使用GraphQL

  • 分享至 

  • xImage
  •  

文章重點

  • 在Next.js 13專案中導入和設置Apollo Client 3進行GraphQL查詢
  • Apollo Client的基本架構及其運作方式
  • 使用Codegen工具自動生成所需的GraphQL查詢和變更的hook
  • 如何使用nx run指令來執行codegen

本文

今天我們將導入graphql,我們這次使用的是Apollo Client 3,Apollo Client是一個完整的GraphQL管理數據的解決方案,它使開發人員可以輕鬆地從伺服器查詢數據,然後將數據存儲在本地。

我們可以先看一下是如何用做的:(圖片來源: Link)
https://ithelp.ithome.com.tw/upload/images/20230930/20108931Ycm4Y52WRj.png

接下來我們安裝相關套件:

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
https://ithelp.ithome.com.tw/upload/images/20230930/20108931DsDRGVUaPk.png

		"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
https://ithelp.ithome.com.tw/upload/images/20230930/20108931os8CWuG4Vs.png
接著我們可以看到codegen幫我們創建出apps\iron-ecommerce-next\__generated__\generated-hooks.ts


總結

本文介紹了如何在Next.js中導入和設置Apollo Client 3。並通過使用Codegen工具,來自動生成所需的GraphQL查詢和變更的hook。最後使用Nx提供的run commands來執行我們得Codegen,下一章將會試著使用graphql資料,不過由於我們沒有server,所以會先使用mock方式來創建假資料。


上一篇
14.【從前端到全端,Nextjs+Nestjs】創建商店頁面-加入狀態管理
下一篇
16.【從前端到全端,Nextjs+Nestjs】使用Mock來模擬GraphQL
系列文
由前向後,從前端邁向全端30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言