API,即应用程序接口,是你的服务与外界交流的窗口。它就像是你服务的门卫,决定了谁可以进来,以及他们可以做什么。通过API接口,用户可以请求数据、提交信息、执行操作等。
一、项目结构规划
首先,我们需要规划项目的整体结构。一个典型的Go Web项目结构可能如下:
/api
/v1
user.go
/v2
user.go
/models
user.go
/utils
crypto.go
database.go
main.go
在这个例子中,我们有一个api目录,其中包含了不同版本的API接口。在v1和v2目录中,都有user.go文件,用于处理与用户相关的API接口。在models目录中,存放了与数据模型相关的代码,而在utils目录中,存放了一些辅助函数和工具类。
二、API接口设计
在Go中,我们可以使用标准库的net/http包来创建HTTP服务器和处理HTTP请求。以下是一个简单的API接口示例:
func handleGetUser(w http.ResponseWriter, r *http.Request) {
// 获取用户ID
id := r.URL.Query().Get("id")
// 调用模型层获取用户信息
user, err := models.GetUser(id)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// 将用户信息转换为JSON格式并返回
json.NewEncoder(w).Encode(user)
}
在这个例子中,我们定义了一个处理GET请求的handleGetUser函数。该函数从URL中获取用户ID,然后调用模型层的GetUser函数获取用户信息。最后,我们将用户信息转换为JSON格式并返回给客户端。
三、用户认证
为了实现用户认证,我们可以使用JWT(JSON Web Tokens)来生成和验证用户令牌。以下是一个使用Go标准库中的crypto/hmac和crypto/sha256来实现JWT签名的示例:
func generateToken(user *models.User) (string, error) {
// 生成随机字符串作为密钥
key := make([]byte, 32)
if _, err := rand.Read(key); err != nil {
return "", err
}
// 将用户信息转换为JSON格式
payload := make(map[string]interface{})
payload["id"] = user.Id
payload["username"] = user.Username
payload["exp"] = time.Now().Add(time.Hour * 72).Unix() // 设置令牌过期时间为72小时后
// 对payload进行Base64编码并拼接密钥和payload字符串,生成token字符串
token := jose.NewSignedJWT(payload, &jose.Signer{
Algorithm: jose.HS256,
Key: key,
})
tokenString, err := token.CompactSerialize()
if err != nil {
return "", err
}
return tokenString, nil
}
在这个例子中,我们使用rand.Read函数生成了一个随机的32字节密钥,然后根据用户信息生成了JWT的payload。最后,我们使用jose.NewSignedJWT函数和密钥对payload进行签名,然后使用token.CompactSerialize函数将生成的token字符串返回给客户端。