Go + Gin 搭建 RESTful API 服务
2026-05-09 · Go
用 Go 的 Gin 框架搭建后端 API 非常轻量。核心结构如下:
r := gin.Default()
api := r.Group("/api/v1")
api.GET("/users/:id", getUser)
api.POST("/users", createUser)
r.Run(":8080")
Gin 的路由分组 + 中间件机制很优雅。比如 JWT 认证只需要一行:
protected := api.Group("")
protected.Use(middleware.JWTAuth(secret))
所有 protected 下的路由自动走鉴权,干净利落。
微信小程序登录流程梳理
2026-05-08 · 微信小程序
小程序登录的核心流程就三步:
- 前端调用 wx.login() 拿到临时 code
- 把 code 发给自己的后端
- 后端拿 code 调微信的 code2Session 接口换 openid
// 后端 Go 伪代码
func wxLogin(code string) {
resp := http.Get(
"https://api.weixin.qq.com/sns/jscode2session" +
"?appid=" + appID +
"&secret=" + appSecret +
"&js_code=" + code +
"&grant_type=authorization_code",
)
// 从 resp 中取 openid,生成 JWT token 返回前端
}
拿到 openid 后生成自己的 JWT token 返回前端即可,不需要存 session。注意 code 只能用一次,5 分钟过期。
Redis 实现接口限流
2026-05-07 · Redis
用 Redis 的 INCR + EXPIRE 实现固定窗口限流,简单有效:
func Allow(rdb *redis.Client, key string, limit int64, ttl time.Duration) bool {
count, _ := rdb.Incr(ctx, key).Result()
if count == 1 {
rdb.Expire(ctx, key, ttl) // 首次设置过期时间
}
return count <= limit
}
Key 按用户 + 日期设计,比如 ai_rate:user_123:20260507,TTL 设到当天 24:00 自动过期。这样每天自动重置,无需手动清理。
如果是 VIP 用户不受限制,只需要在中间件里判断用户角色,VIP 直接放行即可。
Docker Compose 一键部署 Go + PostgreSQL + Redis
2026-05-06 · Docker
一个典型的 docker-compose.yml 长这样:
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: appdb
redis:
image: redis:7-alpine
server:
build: ./server
ports:
- "8080:8080"
environment:
DB_HOST: postgres
REDIS_ADDR: redis:6379
depends_on:
- postgres
- redis
几个要点:
- 服务间用服务名互相访问,如 DB_HOST: postgres
- Go 的 Dockerfile 用多阶段构建,编译阶段用 golang:alpine,运行阶段用 alpine,镜像只有十几 MB
- 数据卷别忘挂载,不然容器重建数据就没了
uni-app 开发小程序踩坑记录
2026-05-05 · 前端
用 uni-app 开发微信小程序,几个常见问题:
环境变量区分开发/生产
根目录放两个文件:
# .env.development
VITE_BASE_URL=http://localhost:8080
# .env.production
VITE_BASE_URL=https://your-domain.com
代码里用 import.meta.env.VITE_BASE_URL 读取,打包时自动切环境。
网络请求封装
不要到处写 uni.request,统一封装一层处理 token 注入和错误处理:
function request(url, options) {
const token = uni.getStorageSync('token')
return new Promise((resolve, reject) => {
uni.request({
url: BASE_URL + url,
header: { Authorization: 'Bearer ' + token },
success(res) {
if (res.statusCode === 401) {
// 跳转登录
}
resolve(res.data)
},
fail(err) {
reject(new Error(err.errMsg || '网络请求失败'))
}
})
})
}
上传注意事项
- manifest.json 开启 "lazyCodeLoading": "requiredComponents",不然上传时会有警告
- 服务器域名必须在小程序后台「服务器域名」中配置,且要求 HTTPS
- 域名需要完成 ICP 备案