后端:使用 Go + ConnectRPC 实现一个服务,支持基础的加减乘除运算。 前端:使用 Next.js 构建UI,包含输入框、操作符选择和结果展示。做一个计算器
时间: 2025-06-25 19:04:47 浏览: 7
### 实现方案概述
以下是关于如何使用 Go 和 ConnectRPC 创建支持加减乘除的服务端接口,以及用 Next.js 构建包含输入框、操作符选择和结果展示的计算器前端界面的具体方法。
---
### 后端服务设计与实现 (Go + ConnectRPC)
#### 1. 定义 Protobuf 文件
Protobuf 是 ConnectRPC 的基础协议定义工具。可以通过以下方式定义一个简单的 `CalculatorService` 接口:
```protobuf
syntax = "proto3";
package calculator;
service Calculator {
rpc Compute(ComputeRequest) returns (ComputeResponse);
}
message ComputeRequest {
double operand1 = 1;
string operator = 2; // "+", "-", "*", "/"
double operand2 = 3;
}
message ComputeResponse {
double result = 1;
}
```
此文件描述了一个名为 `Calculator` 的服务,其中包含一个 `Compute` 方法用于执行计算逻辑[^3]。
#### 2. 使用 Go 编写服务端代码
通过安装 `connect-go` 库并生成对应的 stubs 来创建服务端逻辑:
```go
package main
import (
"context"
"fmt"
"log"
pb "path/to/generated/calculator" // 替换为实际路径
"github.com/bufbuild/connect-go"
)
type Server struct{}
func (s *Server) Compute(ctx context.Context, req *connect.Request[pb.ComputeRequest]) (*connect.Response[pb.ComputeResponse], error) {
operator := req.Msg.GetOperator()
operand1 := req.Msg.GetOperand1()
operand2 := req.Msg.GetOperand2()
var result float64
switch operator {
case "+":
result = operand1 + operand2
case "-":
result = operand1 - operand2
case "*":
result = operand1 * operand2
case "/":
if operand2 != 0 {
result = operand1 / operand2
} else {
return nil, fmt.Errorf("division by zero is not allowed")
}
default:
return nil, fmt.Errorf("unsupported operation: %v", operator)
}
resp := &pb.ComputeResponse{
Result: result,
}
return connect.NewResponse(resp), nil
}
func main() {
listener, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatalf("failed to start server: %v", err)
}
handler := connect.NewHandler(
pb.NewCalculatorServiceHandler(&Server{}),
connect.WithCompression(connect.CompressionGZIP),
)
fmt.Println("Starting server on :8080...")
err = http.Serve(listener, handler)
if err != nil {
log.Fatalf("server failed: %v", err)
}
}
```
这段代码实现了基本的四则运算逻辑,并将其暴露给客户端调用[^4]。
---
### 前端 UI 设计与实现 (Next.js)
#### 1. 设置项目环境
初始化一个新的 Next.js 项目并通过 npm 或 yarn 添加必要的依赖项:
```bash
npx create-next-app@latest my-calculator
cd my-calculator
npm install axios @bufbuild/protobuf --save
```
#### 2. 创建组件结构
在页面中构建一个表单供用户输入两个数值及选择的操作符,并显示最终的结果。
##### 页面布局 (`pages/index.tsx`)
```tsx
import { useState } from 'react';
import axios from 'axios';
export default function Home() {
const [input1, setInput1] = useState('');
const [input2, setInput2] = useState('');
const [operator, setOperator] = useState('+');
const [result, setResult] = useState<number | null>(null);
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
try {
const response = await axios.post('http://localhost:8080/compute', {
operand1: parseFloat(input1),
operator,
operand2: parseFloat(input2),
});
setResult(response.data.result); // Assuming the backend sends back a JSON object with key "result".
} catch (error) {
console.error(error);
alert('An error occurred while processing your request.');
}
}
return (
<div>
<h1>Simple Calculator</h1>
<form onSubmit={handleSubmit}>
<input type="number" value={input1} onChange={(e) => setInput1(e.target.value)} placeholder="Enter first number..." />
<select value={operator} onChange={(e) => setOperator(e.target.value)}>
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input type="number" value={input2} onChange={(e) => setInput2(e.target.value)} placeholder="Enter second number..." />
<button type="submit">Calculate</button>
</form>
{result !== null && <p>Result: {result}</p>}
</div>
);
}
```
该部分展示了完整的交互流程,包括获取用户输入、发送 HTTP 请求到后端 API 并更新状态以反映最新结果[^5]。
---
### 部署建议
- **后端部署**: 可以考虑将 Go 应用程序打包成容器镜像并通过 Docker 运行。
- **前端托管**: 利用 Vercel 提供的无缝集成特性快速发布 Next.js 应用至云端。
---
阅读全文