Skip to content

Commit 74b6ebd

Browse files
committed
feat: connect to backend!
1 parent 040e381 commit 74b6ebd

File tree

18 files changed

+1018
-537
lines changed

18 files changed

+1018
-537
lines changed

docs/07-optional-backend-integration.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44

55
我们提供了一个模板后端项目 [tobenot/Basic-Web-Game-Backend](https://github.com/tobenot/Basic-Web-Game-Backend),您可以直接使用它,或基于此模板创建自己的后端项目。该后端通过 **GitHub Packages** 发布一个私有的npm包来共享API类型契约。
66

7+
**🎮 新增:后端功能演示模块**
8+
9+
本模板现在包含一个完整的后端集成演示模块 (`src/games/demo-with-backend`),展示了如何实现:
10+
- 魔法链接登录
11+
- tRPC类型安全API调用
12+
- JWT令牌管理
13+
- 用户状态管理
14+
715
您估计会想使用自己的后端项目,请将下文中的所有 `@<您的GitHub用户名>` 替换为您的实际GitHub用户名。
816

917
---
@@ -12,6 +20,25 @@
1220

1321
如果您已经熟悉流程,可以直接按照以下步骤操作:
1422

23+
### **🎮 体验后端演示(推荐)**
24+
25+
1. **启动后端服务**
26+
```bash
27+
# 在 Basic-Web-Game-Backend 项目中
28+
npm run dev
29+
```
30+
31+
2. **访问演示**
32+
启动前端开发服务器后,访问 `/demo-with-backend` 路由
33+
34+
3. **体验功能**
35+
- 输入邮箱地址
36+
- 检查邮箱或控制台获取魔法链接
37+
- 点击链接完成登录
38+
- 查看用户仪表板
39+
40+
### **🔧 手动集成后端**
41+
1542
1. **创建 `.npmrc` 文件**
1643
在项目根目录添加 `.npmrc` 文件,并包含以下内容:
1744
```ini
@@ -196,6 +223,59 @@ jobs:
196223
197224
---
198225
226+
## **🎮 后端演示模块详解**
227+
228+
### **模块结构**
229+
230+
```
231+
src/games/demo-with-backend/
232+
├── components/
233+
│ ├── LoginScreen.tsx # 登录界面组件
234+
│ └── Dashboard.tsx # 用户仪表板组件
235+
├── hooks/
236+
│ └── useAuth.ts # 认证状态管理Hook
237+
├── services/
238+
│ └── trpc.ts # tRPC客户端配置
239+
├── index.tsx # 模块入口
240+
└── README.md # 模块说明文档
241+
```
242+
243+
### **核心功能**
244+
245+
1. **魔法链接登录**
246+
- 用户输入邮箱地址
247+
- 后端发送包含魔法链接的邮件
248+
- 用户点击链接完成登录
249+
250+
2. **JWT令牌管理**
251+
- 自动解析和验证JWT令牌
252+
- 令牌过期自动清理
253+
- 登录状态持久化
254+
255+
3. **tRPC集成**
256+
- 类型安全的API调用
257+
- 自动错误处理
258+
- 完整的TypeScript支持
259+
260+
### **如何移除**
261+
262+
如果不需要后端功能,可以轻松移除:
263+
264+
1. **删除模块**
265+
```bash
266+
rm -rf src/games/demo-with-backend
267+
```
268+
269+
2. **移除路由**
270+
`src/App.tsx` 中删除相关导入和路由
271+
272+
3. **清理依赖**(可选):
273+
```bash
274+
npm uninstall @trpc/client
275+
```
276+
277+
---
278+
199279
## **总结**
200280
通过这种方式,前后端团队可以解耦,同时保持类型安全:
201281
1. **后端**:每次推送到`main`分支时,自动发布一个包含最新API类型的新版本包。
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# 后端集成指南
2+
3+
## 前端现状
4+
5+
我们正在开发一个基于React + TypeScript的前端游戏项目,需要与后端进行集成。目前遇到了一些连接问题,需要后端配合解决。
6+
7+
## 当前问题
8+
9+
### 1. 404 Not Found 错误
10+
```
11+
Failed to load resource: the server responded with a status of 404 (Not Found)
12+
/api/trpc/auth.requestLoginLink?batch=1:1
13+
```
14+
15+
### 2. JSON解析错误
16+
```
17+
Failed to execute 'json' on 'Response': Unexpected end of JSON input
18+
```
19+
20+
### 3. tRPC类型不匹配
21+
TypeScript编译时出现tRPC类型不兼容的错误。
22+
23+
## 前端配置
24+
25+
### 依赖版本
26+
- `@trpc/client`: ^11.4.3
27+
- `@tobenot/basic-web-game-backend-contract`: ^1.0.0
28+
29+
### API端点
30+
前端期望的后端API端点:
31+
- `GET /api/trpc/auth.healthCheck` (健康检查)
32+
- `POST /api/trpc/auth.requestLoginLink` (请求登录链接)
33+
- `POST /api/trpc/auth.verifyMagicToken` (验证魔法令牌)
34+
- `GET /api/trpc/user.getMe` (获取用户信息)
35+
36+
### 请求格式
37+
tRPC批量请求格式:
38+
```json
39+
{
40+
"0": {
41+
"json": {
42+
"email": "[email protected]"
43+
}
44+
}
45+
}
46+
```
47+
48+
## 需要后端配合的事项
49+
50+
### 1. 确认API端点
51+
请确认后端是否提供了以下端点:
52+
- `/api/trpc/auth.healthCheck` (POST) - 健康检查
53+
- `/api/trpc/auth.requestLoginLink` (POST) - 请求登录链接
54+
- `/api/trpc/auth.verifyMagicToken` (POST) - 验证魔法令牌
55+
- `/api/trpc/user.getMe` (GET) - 获取用户信息
56+
57+
### 2. 检查CORS配置
58+
前端运行在 `http://localhost:5173`,需要后端允许跨域请求:
59+
```javascript
60+
// 后端CORS配置示例
61+
app.use(cors({
62+
origin: ['http://localhost:5173', 'http://localhost:3000'],
63+
credentials: true
64+
}));
65+
```
66+
67+
### 3. 验证tRPC配置
68+
确保后端tRPC配置正确:
69+
```javascript
70+
// 后端tRPC配置
71+
const appRouter = router({
72+
auth: authRouter,
73+
user: userRouter,
74+
// ... 其他路由
75+
});
76+
77+
export type AppRouter = typeof appRouter;
78+
```
79+
80+
### 4. 检查响应格式
81+
tRPC期望的响应格式:
82+
```json
83+
{
84+
"result": {
85+
"data": {
86+
"success": true
87+
}
88+
}
89+
}
90+
```
91+
92+
## 测试步骤
93+
94+
### 1. 启动后端服务
95+
```bash
96+
cd Basic-Web-Game-Backend
97+
npm run dev
98+
```
99+
100+
### 2. 测试API端点
101+
```bash
102+
# 测试健康检查
103+
curl -X GET http://localhost:3000/api/trpc/auth.healthCheck \
104+
-H "Content-Type: application/json"
105+
106+
# 测试登录链接请求
107+
curl -X POST http://localhost:3000/api/trpc/auth.requestLoginLink \
108+
-H "Content-Type: application/json" \
109+
-d '{"0":{"json":{"email":"[email protected]"}}}'
110+
```
111+
112+
### 3. 检查前端连接
113+
访问 `http://localhost:5173/demo-with-backend` 查看连接状态。
114+
115+
## 调试信息
116+
117+
### 前端调试
118+
- 打开浏览器开发者工具
119+
- 查看Console和Network标签页
120+
- 页面会显示后端连接状态指示器
121+
122+
### 后端调试
123+
- 检查服务器日志
124+
- 确认端口3000是否被占用
125+
- 验证tRPC路由是否正确注册
126+
127+
## 联系信息
128+
129+
如果遇到问题,请检查:
130+
1. 后端服务是否正常运行在端口3000
131+
2. API端点是否正确配置
132+
3. CORS设置是否允许前端域名
133+
4. tRPC版本是否与前端兼容
134+
135+
## 预期结果
136+
137+
成功集成后,用户应该能够:
138+
1. 在登录页面输入邮箱
139+
2. 收到魔法链接(开发环境下在控制台显示)
140+
3. 点击链接完成登录
141+
4. 看到用户仪表板
142+
143+
---
144+
145+
**注意**:这是一个演示模块,用于展示前后端集成的完整流程。如果不需要后端功能,可以轻松移除整个模块。

docs/letter_to_backend/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
## 🔐 Optional Backend Integration
3+
4+
This template includes a **backend integration demo** that showcases how to integrate with a backend service using tRPC and magic link authentication.
5+
6+
### 🚀 Try the Backend Demo
7+
8+
1. **Start the backend service** (from [Basic-Web-Game-Backend](https://github.com/tobenot/Basic-Web-Game-Backend)):
9+
```bash
10+
npm run dev
11+
```
12+
13+
2. **Access the demo** at `/demo-with-backend` route
14+
15+
3. **Experience the features**:
16+
- Magic link authentication
17+
- Type-safe API calls with tRPC
18+
- JWT token management
19+
- Real-time user state
20+
21+
### 📖 Learn More
22+
23+
For detailed backend integration documentation, see [Backend Integration Guide](./docs/07-optional-backend-integration.md).
24+
25+
### 🗑️ Remove Backend Features
26+
27+
If you don't need backend functionality, you can easily remove it:
28+
29+
1. **Delete the demo module**:
30+
```bash
31+
rm -rf src/games/demo-with-backend
32+
```
33+
34+
2. **Remove the route** from `src/App.tsx`
35+
36+
3. **Clean up dependencies** (optional):
37+
```bash
38+
npm uninstall @trpc/client
39+
```
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
const API_BASE_URL = 'http://localhost:3000';
2+
3+
async function testBackendConnection() {
4+
console.log('🔍 测试后端连接...\n');
5+
6+
// 测试1: 检查服务器是否运行
7+
console.log('1. 检查服务器状态...');
8+
try {
9+
const response = await fetch(`${API_BASE_URL}/api/trpc/auth.healthCheck`, {
10+
method: 'GET',
11+
headers: {
12+
'Content-Type': 'application/json',
13+
}
14+
});
15+
16+
console.log(` 状态码: ${response.status}`);
17+
console.log(` 状态文本: ${response.statusText}`);
18+
19+
if (response.ok) {
20+
console.log(' ✅ 服务器响应正常');
21+
try {
22+
const data = await response.json();
23+
if (data.result?.data?.status === 'ok') {
24+
console.log(' ✅ 健康检查通过');
25+
} else {
26+
console.log(' ⚠️ 健康检查失败');
27+
}
28+
} catch (e) {
29+
console.log(' ⚠️ 无法解析健康检查响应');
30+
}
31+
} else {
32+
console.log(' ❌ 服务器响应异常');
33+
}
34+
35+
// 尝试读取响应内容
36+
try {
37+
const text = await response.text();
38+
console.log(` 响应内容: ${text.substring(0, 200)}...`);
39+
} catch (e) {
40+
console.log(' 无法读取响应内容');
41+
}
42+
43+
} catch (error) {
44+
console.log(` ❌ 连接失败: ${error.message}`);
45+
}
46+
47+
// 测试2: 检查CORS
48+
console.log('\n2. 检查CORS配置...');
49+
try {
50+
const response = await fetch(`${API_BASE_URL}/api/trpc/auth.healthCheck`, {
51+
method: 'OPTIONS',
52+
headers: {
53+
'Origin': 'http://localhost:5173',
54+
'Access-Control-Request-Method': 'GET',
55+
'Access-Control-Request-Headers': 'Content-Type',
56+
}
57+
});
58+
59+
const corsHeaders = response.headers.get('access-control-allow-origin');
60+
if (corsHeaders) {
61+
console.log(` ✅ CORS已配置: ${corsHeaders}`);
62+
} else {
63+
console.log(' ⚠️ 未找到CORS配置');
64+
}
65+
} catch (error) {
66+
console.log(` ❌ CORS检查失败: ${error.message}`);
67+
}
68+
69+
// 测试3: 检查其他端点
70+
console.log('\n3. 检查其他端点...');
71+
const endpoints = [
72+
'auth.requestLoginLink',
73+
'auth.verifyMagicToken',
74+
'user.getMe',
75+
'announcement.getAnnouncement'
76+
];
77+
78+
for (const endpoint of endpoints) {
79+
try {
80+
const response = await fetch(`${API_BASE_URL}/api/trpc/${endpoint}`, {
81+
method: 'POST',
82+
headers: {
83+
'Content-Type': 'application/json',
84+
},
85+
body: JSON.stringify({
86+
0: {
87+
json: endpoint === 'auth.requestLoginLink' ? { email: '[email protected]' } : {}
88+
}
89+
})
90+
});
91+
92+
console.log(` ${endpoint}: ${response.status} ${response.statusText}`);
93+
} catch (error) {
94+
console.log(` ${endpoint}: 连接失败`);
95+
}
96+
}
97+
98+
console.log('\n📋 总结:');
99+
console.log('- 如果看到404错误,说明端点不存在');
100+
console.log('- 如果看到405错误,说明端点存在但方法不对');
101+
console.log('- 如果看到CORS错误,需要配置跨域');
102+
console.log('- 如果看到JSON解析错误,说明响应格式不对');
103+
console.log('\n💡 建议:');
104+
console.log('1. 确保后端服务运行在 http://localhost:3000');
105+
console.log('2. 检查tRPC路由配置');
106+
console.log('3. 验证CORS设置');
107+
console.log('4. 确认API端点路径正确');
108+
}
109+
110+
testBackendConnection().catch(console.error);

0 commit comments

Comments
 (0)