首頁 > 後端開發 > Golang > Go 和 MongoDB:從頭開始建立 CRUD API

Go 和 MongoDB:從頭開始建立 CRUD API

王林
發布: 2024-07-18 08:55:05
原創
893 人瀏覽過

Go and MongoDB: Building a CRUD API from Scratch

想要建立一個具有強大後端的動態 Web 應用程式嗎? Go 和 MongoDB 就是最好的選擇!這種強大的組合使您能夠建立可擴展、高效的 API,輕鬆處理資料建立、讀取、更新和刪除 (CRUD)。

在這個適合初學者的指南中,我們將逐步介紹使用 Go 和 MongoDB 建立簡單的 CRUD API 的過程。我們將介紹基本步驟,提供程式碼範例,並在此過程中提供有用的提示。

入門

首先,讓我們設定我們的環境:

  1. Go 安裝: 從 https://go.dev/dl/ 下載並安裝最新版本的 Go。
  2. MongoDB 設定: 如果您沒有執行 MongoDB,可以從 https://www.mongodb.com/try/download/community 下載並安裝它。
  3. 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"`
}
登入後複製

說明:

  • 我們使用 mongo-driver 套件中的primitive.ObjectID 來表示唯一的 MongoDB 文件 ID。
  • bson 標籤對於將 Go 結構欄位對應到 MongoDB 文件中的對應欄位至關重要。

連接到 MongoDB

我們需要建立與 MongoDB 資料庫的連線。在config目錄下建立config.go檔:

// 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_URI 檢索 MongoDB 連線 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

  1. 環境變數: 使用 MongoDB 連接字串設定 MONGODB_URI 環境變數。
  2. 建置並運行: 使用 go build 建立 Go 應用程序,然後使用 ./my-crud-api 運行它。

測試 API

您可以使用Postman或curl等工具來測試您的API。

  • 建立: 使用包含使用者詳細資料的 JSON 負載向 /users 發送 POST 請求。
  • 閱讀: 向 /users 發送 GET 請求以檢索所有用戶,或向 /users/?id={user_id} 發送 GET 請求以獲取特定用戶。
  • 更新: 使用包含更新的使用者詳細資訊的 JSON 負載向 /users/?id={user_id} 發送 PUT 請求。
  • 刪除: 向 /users/?id={user_id} 發送 DELETE 請求以刪除使用者。

成功秘訣

  • 錯誤處理:始終處理潛在錯誤並傳回有意義的 HTTP 狀態碼。
  • 安全性:為您的 API 實作適當的驗證和授權機制。
  • 資料庫設計:精心設計資料庫架構以優化效能和可擴展性。
  • 文件: 記錄您的 API 端點、請求/回應格式和錯誤代碼。

恭喜! 您已經使用 Go 和 MongoDB 成功建立了基本的 CRUD API。有了這個基礎,您可以擴展 API 以處理更複雜的功能並建立令人印象深刻的 Web 應用程式。繼續學習和探索 Go 和 MongoDB 的無限可能性!

以上是Go 和 MongoDB:從頭開始建立 CRUD API的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板