使用 GraphQL 和 AWS AppSync 结合 Next.js 和 AWS Lambda 构建现代全栈应用

Posted by Panda on 2025-01-06

使用 GraphQL 和 AWS AppSync 结合 Next.js 和 AWS Lambda 构建现代全栈应用

介绍

GraphQL 是一种用于 API 的查询语言,它允许客户端请求仅所需的数据,而不是像 REST API 那样返回固定的数据结构。AWS AppSync 是 Amazon 提供的一种完全托管的 GraphQL 服务,它简化了构建数据驱动应用的方式,使得开发者可以轻松地与不同数据源进行交互。AWS Lambda 是一种无服务器计算服务,可让您运行代码而无需预置或管理服务器。

在这篇文章中,我们将介绍如何使用 GraphQL 和 AWS AppSync 结合 AWS Lambda 和 Next.js 构建现代全栈应用。通过详细的步骤和解释,帮助初学者更好地理解和实践这些技术。

1. GraphQL 基础

1.1 什么是 GraphQL?

GraphQL 是由 Facebook 开发的用于 API 的查询语言。它允许客户端准确地描述所需的数据结构,并通过单个请求获取数据。主要特点包括:

  • 强类型系统:每个 GraphQL API 都有一个强类型的 schema。
  • 单一端点:所有请求都通过一个端点进行。
  • 高效的查询:客户端可以请求精确的数据,避免过多的数据传输。

1.2 GraphQL 示例

以下是一个简单的 GraphQL 查询示例:

1
2
3
4
5
6
7
query {
getUser(id: "1") {
id
name
email
}
}

这个查询将返回用户 ID 为 “1” 的用户的 ID、名称和电子邮件。

2. AWS AppSync 和 AWS Lambda 基础

2.1 什么是 AWS AppSync?

AWS AppSync 是 Amazon 提供的完全托管的 GraphQL 服务,它简化了构建数据驱动应用的方式。AppSync 可以与多种数据源(如 DynamoDB、Lambda、Elasticsearch)集成,提供实时订阅功能,并支持离线数据同步。

2.2 什么是 AWS Lambda?

AWS Lambda 是一种无服务器计算服务,可让您运行代码而无需预置或管理服务器。Lambda 自动扩展并处理高可用性。您只需为使用的计算资源付费。

3. 创建一个 GraphQL API

3.1 设置 AWS AppSync

  1. 登录 AWS 管理控制台,导航到 AppSync 服务。
  2. 点击 “Create API”,选择 “Build from scratch”。
  3. 输入 API 名称,并选择默认设置。
  4. 点击 “Create”。

3.2 定义 GraphQL Schema

在 AppSync 控制台中,定义以下 GraphQL schema:

1
2
3
4
5
6
7
8
9
10
11
12
13
type Query {
getUser(id: ID!): User
}

type Mutation {
createUser(id: ID!, name: String!, email: String!): User
}

type User {
id: ID!
name: String!
email: String!
}

3.3 创建 AWS Lambda 函数

  1. 登录 AWS 管理控制台,导航到 Lambda 服务。
  2. 点击 “Create function”,选择 “Author from scratch”。
  3. 输入函数名称,并选择 “Node.js 18.x” 作为运行时。
  4. 为函数添加基本代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
exports.handler = async (event) => {
const { field, arguments } = event;

const users = [
{ id: "1", name: "Alice", email: "alice@example.com" },
{ id: "2", name: "Bob", email: "bob@example.com" }
];

if (field === "getUser") {
return users.find(user => user.id === arguments.id);
}

if (field === "createUser") {
const newUser = { id: arguments.id, name: arguments.name, email: arguments.email };
users.push(newUser);
return newUser;
}

return null;
};

3.4 连接 AWS Lambda 数据源

  1. 在 AppSync 控制台中,导航到 “Data Sources”。
  2. 点击 “Create Data Source”,选择 “AWS Lambda”。
  3. 输入数据源名称,并选择刚刚创建的 Lambda 函数。

3.5 配置解析器

  1. 在 AppSync 控制台中,导航到 “Resolvers”。
  2. getUsercreateUser 配置解析器,映射到 Lambda 函数。

详细步骤可以参考 AWS 官方文档

3.6 配置解析器的具体步骤

在配置解析器时,需要为 getUsercreateUser 操作指定 Lambda 函数作为它们的解析器。以下是详细步骤:

  1. 在 “Resolvers” 页面,选择 Query 下面的 getUser
  2. 点击 “Attach”,然后选择刚创建的 Lambda 数据源。
  3. 在 “Request Mapping Template” 中,使用以下模板:
1
2
3
4
{
"field": "getUser",
"arguments": $utils.toJson($context.arguments)
}
  1. 在 “Response Mapping Template” 中,使用以下模板:
1
$utils.toJson($context.result)
  1. createUser 操作重复上述步骤,修改 “Request Mapping Template” 中的 fieldcreateUser

4. 前端集成

4.1 安装 AWS Amplify

AWS Amplify 是一个开源库,简化了与 AWS 服务的集成。安装 Amplify:

1
npm install aws-amplify @aws-amplify/ui-react

4.2 初始化 AWS Amplify 并生成 aws-exports.js 文件

首先,需要全局安装 AWS Amplify CLI:

1
npm install -g @aws-amplify/cli

然后,在你的 Next.js 项目根目录下,运行以下命令来初始化 Amplify 项目:

1
amplify init

你将会被提示输入一些配置信息,如项目名称、环境名称、AWS 区域等。根据你的需求进行配置。

接下来,运行以下命令来添加 AWS AppSync API:

1
amplify add api

在配置过程中,你会被问到以下问题:

  • 请选择您想要添加的 API 类型:选择 GraphQL
  • 为您的 API 提供一个友好的名称:输入你的 API 名称
  • 为您的 API 提供一个 API Key:选择 API Key
  • API Key 到期时间:选择合适的过期时间
  • 是否有现有的 schema:选择 No
  • 是否要导入 schema:选择 No
  • 是否想要一个样本 schema:选择 Yes

选择一个样本 schema,或者根据你的需求自定义 schema。

最后,运行以下命令来部署 API:

1
amplify push

这将会创建并配置 AWS AppSync API,并生成 aws-exports.js 配置文件。

4.3 使用 aws-exports.js 配置文件

在你的 Next.js 项目中,aws-exports.js 文件会在项目根目录的 src 文件夹或 src 文件夹的子文件夹中生成。你需要将这个文件导入到你的项目中,并使用它来配置 AWS Amplify。

例如,在 pages/_app.js 文件中:

1
2
3
4
5
6
7
8
9
10
import Amplify from 'aws-amplify';
import awsconfig from '../src/aws-exports'; // 确保路径正确

Amplify.configure(awsconfig);

function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}

export default MyApp;

4.4 使用 GraphQL 查询和变更

创建一个 GraphQL 查询和变更文件(如 graphql/queries.jsgraphql/mutations.js):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// graphql/queries.js
export const getUser = /* GraphQL */ `
query GetUser($id: ID!) {
getUser(id: $id) {
id
name
email
}
}
`;

// graphql/mutations.js
export const createUser = /* GraphQL */ `
mutation CreateUser($id: ID!, $name: String!, $email: String!) {
createUser(id: $id, name: $name, email: $email) {
id
name
email
}
}
`;

4.5 在 Next.js 页面中使用 GraphQL

在 Next.js 页面中使用 GraphQL 查询和变更:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import { API, graphqlOperation } from 'aws-amplify';
import { useState } from 'react';
import { getUser } from '../graphql/queries';
import { createUser } from '../graphql/mutations';

const HomePage = () => {
const [user, setUser] = useState(null);
const [newUser, setNewUser] = useState({ id: '', name: '', email: '' });

const fetchUser = async (userId) => {
try {
const userData = await API.graphql(graphqlOperation(getUser, { id: userId }));
setUser(userData.data.getUser);
} catch (err) {
console.error('Error fetching user:', err);
}
};

const addUser = async () => {
try {
const userData = await API.graphql(graphqlOperation(createUser, newUser));
setUser(userData.data.createUser);
setNewUser({ id: '', name: '', email: '' });
} catch (err) {
console.error('Error creating user:', err);
}
};

return (
<div>
<h1>GraphQL and AWS AppSync with Next.js</h1>
<div>
<h2>Fetch User</h2>
<input
type="text"
placeholder="User ID"
onChange={(e) => fetchUser(e.target.value)}
/>
{user && (
<div>
<p>ID: {user.id}</p>
<p>Name: {user.name}</p>
<p>Email: {user.email}</p>
</div>
)}
</div>
<div>
<h2>Create User</h2>
<input
type="text"
placeholder="ID"
value={newUser.id}
onChange={(e) => setNewUser({ ...newUser, id: e.target.value })}
/>
<input
type="text"
placeholder="Name"
value={newUser.name}
onChange={(e) => setNewUser({ ...newUser, name: e.target.value })}
/>
<input
type="text"
placeholder="Email"
value={newUser.email}
onChange={(e) => setNewUser({ ...newUser, email: e.target.value })}
/>
<button onClick={addUser}>Create User</button>
</div>
</div>
);
};

export default HomePage;

5. 结论

通过使用 GraphQL 和 AWS AppSync,我们可以构建强大且高效的全栈应用。GraphQL 提供了灵活的数据查询方式,而 AWS AppSync 则简化了与各种数据源的集成,并提供了实时和离线支持。结合 Next.js 和 AWS Lambda,可以让前端全栈开发者更好地实践和练习这些技术。