Go 和 MongoDB:从头构建 CRUD API
想要创建一个具有强大后端的动态 Web 应用程序吗?Go 和 MongoDB 就是最佳选择!这种强大的组合使您能够构建可扩展、高效的 API,轻松处理数据的创建、读取、更新和删除 (CRUD)。
在本指南中,我们将逐步讲解如何使用 Go 和 MongoDB 构建一个简单的 CRUD API,适合初学者。我们将讲解基本步骤、提供代码示例,并附带一些实用技巧。
入门
首先,让我们设置我们的环境:
- Go 安装:从https://go.dev/dl/下载并安装最新版本的 Go 。
- MongoDB 设置:如果您没有运行 MongoDB,您可以从https://www.mongodb.com/try/download/community下载并安装它。
- IDE 或文本编辑器:选择您喜欢的编码环境。一些常用的选项包括 VS Code、GoLand 或 Atom。
项目结构:
创建一个新的项目目录并像这样组织您的文件:
my-crud-api/
├── main.go
├── models/
│ └── user.go
├── handlers/
│ └── user.go
└── config/
└── config.go
定义我们的模型
让我们从定义数据模型开始。在本例中,我们将创建一个简单的User
结构体:
// models/user.go
package models
import (
"go.mongodb.org/mongo-driver/bson/primitive"
)
type User struct {
ID primitive.ObjectID `bson:"_id,omitempty"`
Name string `bson:"name,omitempty"`
Email string `bson:"email,omitempty"`
Age int `bson:"age,omitempty"`
Active bool `bson:"active,omitempty"`
}
解释:
- 我们使用
primitive.ObjectID
来自mongo-driver
包的来表示唯一的 MongoDB 文档 ID。 - 标签
bson
对于将我们的 Go 结构字段映射到 MongoDB 文档中的相应字段至关重要。
连接到 MongoDB
我们需要建立与 MongoDB 数据库的连接。在目录config.go
中创建一个文件config
:
// config/config.go
package config
import (
"context"
"fmt"
"os"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func ConnectToMongoDB() (*mongo.Client, error) {
uri := os.Getenv("MONGODB_URI")
if uri == "" {
return nil, fmt.Errorf("MONGODB_URI is not set")
}
clientOptions := options.Client().ApplyURI(uri)
client, err := mongo.Connect(context.Background(), clientOptions)
if err != nil {
return nil, err
}
err = client.Ping(context.Background(), nil)
if err != nil {
return nil, err
}
return client, nil
}
解释:
- 我们使用
os.Getenv
环境变量来检索 MongoDB 连接 URIMONGODB_URI
。请确保在您的环境中设置此变量。 - 我们使用该
mongo-driver
包连接到 MongoDB 数据库并执行 ping 数据库等基本操作。
建筑搬运工
现在,让我们为 CRUD 操作构建 API 处理程序。在handlers
目录中,创建一个user.go
文件:
// handlers/user.go
package handlers
import (
"context"
"encoding/json"
"fmt"
"net/http"
"github.com/your-username/my-crud-api/config"
"github.com/your-username/my-crud-api/models"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)
// Create a new user
func CreateUser(w http.ResponseWriter, r *http.Request) {
client, err := config.ConnectToMongoDB()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer client.Disconnect(context.Background())
var user models.User
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
collection := client.Database("your_database_name").Collection("users")
result, err := collection.InsertOne(context.Background(), user)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(result)
}
// Get all users
func GetAllUsers(w http.ResponseWriter, r *http.Request) {
client, err := config.ConnectToMongoDB()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer client.Disconnect(context.Background())
collection := client.Database("your_database_name").Collection("users")
cursor, err := collection.Find(context.Background(), bson.D{})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer cursor.Close(context.Background())
var users []models.User
for cursor.Next(context.Background()) {
var user models.User
if err := cursor.Decode(&user); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
users = append(users, user)
}
json.NewEncoder(w).Encode(users)
}
// Get a user by ID
func GetUserByID(w http.ResponseWriter, r *http.Request) {
client, err := config.ConnectToMongoDB()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer client.Disconnect(context.Background())
id, err := primitive.ObjectIDFromHex(r.URL.Query().Get("id"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
collection := client.Database("your_database_name").Collection("users")
var user models.User
if err := collection.FindOne(context.Background(), bson.M{"_id": id}).Decode(&user); err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
json.NewEncoder(w).Encode(user)
}
// Update a user
func UpdateUser(w http.ResponseWriter, r *http.Request) {
client, err := config.ConnectToMongoDB()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer client.Disconnect(context.Background())
id, err := primitive.ObjectIDFromHex(r.URL.Query().Get("id"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
var updatedUser models.User
if err := json.NewDecoder(r.Body).Decode(&updatedUser); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
collection := client.Database("your_database_name").Collection("users")
filter := bson.M{"_id": id}
update := bson.M{"$set": updatedUser}
result, err := collection.UpdateOne(context.Background(), filter, update)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(result)
}
// Delete a user
func DeleteUser(w http.ResponseWriter, r *http.Request) {
client, err := config.ConnectToMongoDB()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer client.Disconnect(context.Background())
id, err := primitive.ObjectIDFromHex(r.URL.Query().Get("id"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
collection := client.Database("your_database_name").Collection("users")
result, err := collection.DeleteOne(context.Background(), bson.M{"_id": id})
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(result)
}
解释:
- 我们实现 CRUD 操作:
CreateUser
、GetAllUsers
、GetUserByID
、UpdateUser
和DeleteUser
。 - 每个函数连接到 MongoDB,检索集合,执行相应的操作,并返回 JSON 响应。
- 我们处理潜在的错误并返回适当的 HTTP 状态代码。
设置主应用程序
最后,让我们将所有内容整合到我们的main.go
文件中:
// main.go
package main
import (
"fmt"
"log"
"net/http"
"github.com/your-username/my-crud-api/handlers"
)
func main() {
http.HandleFunc("/users", handlers.CreateUser)
http.HandleFunc("/users", handlers.GetAllUsers)
http.HandleFunc("/users/", handlers.GetUserByID)
http.HandleFunc("/users/", handlers.UpdateUser)
http.HandleFunc("/users/", handlers.DeleteUser)
fmt.Println("Server running on port 8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
解释:
- 我们使用相应的 HTTP 端点注册 API 处理程序。
- 我们启动服务器并监听端口 8080。
运行 API
- 环境变量:
MONGODB_URI
使用 MongoDB 连接字符串设置环境变量。 - 构建并运行:使用构建 Go 应用程序
go build
,然后使用运行它./my-crud-api
。
测试 API
您可以使用 Postman 或 curl 等工具测试您的 API。
- 创建:
/users
发送包含用户详细信息的 JSON 有效负载的POST 请求。 - 读取:发送 GET 请求以
/users
检索所有用户或/users/?id={user_id}
获取特定用户。 - 更新:
/users/?id={user_id}
发送包含更新的用户详细信息的 JSON 有效负载的PUT 请求。 - 删除:发送 DELETE 请求以
/users/?id={user_id}
删除用户。
成功秘诀
- 错误处理:始终处理潜在错误并返回有意义的 HTTP 状态代码。
- 安全性:为您的 API 实施适当的身份验证和授权机制。
- 数据库设计:精心设计数据库模式以优化性能和可扩展性。
- 文档:记录您的 API 端点、请求/响应格式和错误代码。
恭喜!您已成功使用 Go 和 MongoDB 构建了基本的 CRUD API。在此基础上,您可以扩展 API 以处理更复杂的功能,并构建出色的 Web 应用程序。继续学习,探索 Go 和 MongoDB 的无限可能!
鏂囩珷鏉ユ簮锛�https://dev.to/aquibpy/go-and-mongodb-building-a-crud-api-from-scratch-10p6