
使用這些基本 REST API 最佳實踐構建出色的 API
表述性狀態傳輸(REST)是一種架構模式,用于指導應用程序編程接口(API)的設計和開發。REST API 已成為產品服務器端與其客戶端之間通信的標準,旨在提升性能、可伸縮性、簡單性、可修改性、可見性、可移植性和可靠性。
本文將探討如何使用 Echo 框架和 MongoDB,通過 Golang 來構建一個用戶管理應用程序。在本教程的結尾,您將學會如何構建 Echo 應用程序、開發 REST API 以及利用 MongoDB 實現數據的持久化存儲。
Echo 是一個高性能且可擴展的 HTTP Web 框架,基于 Golang 開發。它提供了優化的路由、中間件、模板、數據綁定和渲染等功能。
MongoDB 是一種基于文檔的數據庫管理程序,用作關系數據庫的替代方案。MongoDB 支持處理大量分布式數據,并可選擇無縫存儲或檢索信息。
本文中的后續步驟要求您具備一定的 Golang 使用經驗。雖然擁有 MongoDB 的使用經驗會有所幫助,但并非必要條件。
此外,您還需要準備以下內容:
首先,我們需要導航到所需的目錄并在我們的終端中運行以下命令:
mkdir echo-mongo-api && cd echo-mongo-api
這條命令用于創建一個文件夾并進入項目目錄,該目錄名為 echo-mongo-api
。
接下來,我們需要通過運行以下命令來初始化一個 Go 模塊,以便管理項目的依賴關系:
go mod init echo-mongo-api
這條命令會創建一個文件,用于追蹤項目的依賴關系,文件名為 go.mod
。
接下來,我們使用以下命令來安裝所需的依賴項:
go get -u github.com/labstack/echo/v4 go.mongodb.org/mongo-driver/mongo github.com/joho/godotenv github.com/go-playground/validator/v10
github.com/labstack/echo/v4
是一個用于構建 Web 應用程序的框架。
go.mongodb.org/mongo-driver/mongo
是用于連接到 MongoDB 的驅動程序。
github.com/joho/godotenv
是一個用于管理環境變量的庫。
github.com/go-playground/validator/v10
是一個用于驗證結構和字段的庫。
安裝項目依賴項后,我們需要在根目錄main.go
中創建文件并添加以下代碼段:
package main
import (
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
return c.JSON(200, &echo.Map{"data": "Hello from Echo & mongoDB"})
})
e.Logger.Fatal(e.Start(":6000"))
}
上面的代碼片段執行以下操作:
echo.New
?函數初始化了一個 Echo 應用程序。接下來,我們可以通過在終端中運行以下命令來啟動開發服務器來測試我們的應用程序。
為我們的項目建立一個良好的文件夾結構至關重要。良好的項目結構能夠簡化我們在應用程序中處理依賴關系的方式,并且使得我們自己和其他人更容易閱讀代碼庫。
為此,我們需要在項目目錄中創建以下文件夾:configs
、controllers
、models
、responses
?和?routes
。
PS: 該文件包含所有依賴項校驗并由 go 工具管理。我們不必擔心。
configs
用于模塊化項目配置文件
controllers
用于模塊化應用程序邏輯。
models
用于模塊化數據和數據庫邏輯。
responses
用于模塊化文件,描述我們希望 API 給出的響應。這在后面會變得更加清楚。
routes
用于模塊化 URL 模式和處理程序信息。
完成后,我們需要登錄或注冊我們的 MongoDB 帳戶。單擊項目下拉菜單,然后單擊 New Project 按鈕。
輸入 作為項目名稱,單擊 Next,然后單擊 Create Project。
單擊 Build a Database(構建數據庫)
選擇 Shared (共享) 作為數據庫的類型。
單擊 Create 以設置集群。這可能需要一些時間來設置。
接下來,我們需要通過輸入用戶名、密碼,然后單擊創建用戶來創建一個用戶以從外部訪問數據庫。我們還需要添加我們的 IP 地址,以便通過單擊“添加我的當前 IP 地址”按鈕安全地連接到數據庫。然后點擊 完成 和 關閉 保存更改。
保存更改后,我們應該會看到 Database Deployments 屏幕,如下所示:
完成配置后,我們需要將應用程序與創建的數據庫連接起來。為此,請單擊 Connect 按鈕
單擊 Connect your application, 更改Driver 和Version ,如下所示。然后單擊復制圖標以復制連接字符串。
Setup 環境變量
接下來,我們必須使用之前創建的用戶密碼修改復制的連接字符串,并更改數據庫名稱。為此,首先,我們需要在根目錄中創建一個文件.env
,并在此文件中添加以下代碼段:
MONGOURI=mongodb+srv://<YOUR USERNAME HERE>:<YOUR PASSWORD HERE>@cluster0.e5akf.mongodb.net/myFirstDatabese?retryWrites=true&w=majority
下面正確填充的連接字符串示例:
MONGOURI=mongodb+srv://malomz:malomzPassword@cluster0.e5akf.mongodb.net/golangDB?retryWrites=true&w=majority
加載環境變量
完成上述步驟后,我們需要創建一個輔助函數,利用之前安裝的庫來加載環境變量。為此,我們需要導航到configs
文件夾,并在這個文件夾中創建一個名為env.go
的文件,然后添加以下代碼段:
package configs
import (
"log"
"os"
"github.com/joho/godotenv"
)
func EnvMongoURI() string {
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
return os.Getenv("MONGOURI")
}
上面的代碼片段執行以下操作:
EnvMongoURI
的環境變量的值。連接到 MongoDB
要從我們的應用程序連接到MongoDB數據庫,首先,我們需要導航到configs
文件夾,并在這個文件夾中創建一個名為setup.go
的文件,然后添加以下代碼段:
package configs
import (
"context"
"fmt"
"log"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func ConnectDB() *mongo.Client {
client, err := mongo.NewClient(options.Client().ApplyURI(EnvMongoURI()))
if err != nil {
log.Fatal(err)
}
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
err = client.Connect(ctx)
if err != nil {
log.Fatal(err)
}
//ping the database
err = client.Ping(ctx, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("Connected to MongoDB")
return client
}
//Client instance
var DB *mongo.Client = ConnectDB()
//getting database collections
func GetCollection(client *mongo.Client, collectionName string) *mongo.Collection {
collection := client.Database("golangAPI").Collection(collectionName)
return collection
}
上面的代碼片段執行以下操作:
ConnectDB
的函數,該函數首先配置客戶端以使用正確的URI,并檢查是否出現錯誤。其次,我們定義了10秒的連接超時時間。再次,該函數會檢查連接數據庫時是否出現錯誤,如果連接時間超過10秒,則取消連接。最后,該函數會向數據庫發送ping請求以測試連接,并返回客戶端實例。DBConnectDB
?的變量實例,這個實例在創建集合時會非常有用。GetCollection
的函數,用于從數據庫中檢索或創建集合。接下來,我們需要在應用程序啟動時連接到數據庫。為此,我們需要修改如下:
package main
import (
"echo-mongo-api/configs" //add this
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
//run database
configs.ConnectDB()
e.Logger.Fatal(e.Start(":6000"))
}
路由處理程序
完成后,我們需要在文件夾內創建一個文件來管理應用程序中所有用戶相關的路由,如下所示:
package routes
import "github.com/labstack/echo/v4"
func UserRoute(e *echo.Echo) {
//All routes related to users comes here
}
接下來,我們需要將新創建的路由附加到 http.服務器,修改如下所示:
package main
import (
"echo-mongo-api/configs"
"echo-mongo-api/routes" //add this
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
//run database
configs.ConnectDB()
//routes
routes.UserRoute(e) //add this
e.Logger.Fatal(e.Start(":6000"))
}
響應類型
接下來,我們需要創建一個可復用的結構體來描述API的響應。為此,請導航到user_response.go
文件夾,并在該文件夾中創建一個文件,然后添加以下代碼段:
package responses
import (
"github.com/labstack/echo/v4"
)
type UserResponse struct {
Status int json:"status"
Message string json:"message"
Data *echo.Map json:"data"
}
上面的描述創建了一個結構體,該結構體包含 Status
、Message
和 Data
屬性,以表示API的響應類型。
這里,UserResponse
是結構體的名稱,而 Status
、Message
和 Data
是其屬性。json:”status”
、json:”message”
和 json:”data”
是所謂的結構體標簽(struct tags),它們允許我們為相應的結構體屬性附加元信息。換句話說,我們使用這些標簽來重新格式化API返回的JSON響應中的字段名。
接下來,我們需要一個模型來表示我們的應用程序數據。為此,我們需要導航到該文件夾,并在此文件夾中創建modelsuser_model.go
文件并添加下面的代碼段:
package models
import "go.mongodb.org/mongo-driver/bson/primitive"
type User struct {
Id primitive.ObjectID json:"id,omitempty"
Name string json:"name,omitempty" validate:"required"
Location string json:"location,omitempty" validate:"required"
Title string json:"title,omitempty" validate:"required"
}
上面的代碼片段執行以下操作:
創建用戶終端節點
通過模型設置,我們現在可以創建一個函數來創建用戶。為此,我們需要導航到該文件夾,并在此文件夾中創建一個文件并添加下面的代碼段:
package controllers
import (
"echo-mongo-api/configs"
"echo-mongo-api/models"
"echo-mongo-api/responses"
"net/http"
"time"
"github.com/go-playground/validator/v10"
"github.com/labstack/echo/v4"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"golang.org/x/net/context"
)
var userCollection *mongo.Collection = configs.GetCollection(configs.DB, "users")
var validate = validator.New()
func CreateUser(c echo.Context) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
var user models.User
defer cancel()
//validate the request body
if err := c.Bind(&user); err != nil {
return c.JSON(http.StatusBadRequest, responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
//use the validator library to validate required fields
if validationErr := validate.Struct(&user); validationErr != nil {
return c.JSON(http.StatusBadRequest, responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &echo.Map{"data": validationErr.Error()}})
}
newUser := models.User{
Id: primitive.NewObjectID(),
Name: user.Name,
Location: user.Location,
Title: user.Title,
}
result, err := userCollection.InsertOne(ctx, newUser)
if err != nil {
return c.JSON(http.StatusInternalServerError, responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
return c.JSON(http.StatusCreated, responses.UserResponse{Status: http.StatusCreated, Message: "success", Data: &echo.Map{"data": result}})
}
上面的代碼片段執行以下操作:
userCollection
和 validate
變量,分別用于創建集合和使用之前安裝的庫來驗證模型。這里提到的庫是 github.com/go-playground/validator/v10
。接下來,我們需要使用路由 API URL 和相應的控制器進行更新,如下所示:
package routes
import (
"echo-mongo-api/controllers" //add this
"github.com/labstack/echo/v4"
)
func UserRoute(e *echo.Echo) {
e.POST("/user", controllers.CreateUser) //add this
}
獲取用戶終端節點
要獲取用戶的詳細信息,我們需要修改如下:
package controllers
import (
//other import goes here
"go.mongodb.org/mongo-driver/bson" //add this
)
var userCollection *mongo.Collection = configs.GetCollection(configs.DB, "users")
var validate = validator.New()
func CreateUser(c echo.Context) error {
//create user code goes here
}
func GetAUser(c echo.Context) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
userId := c.Param("userId")
var user models.User
defer cancel()
objId, _ := primitive.ObjectIDFromHex(userId)
err := userCollection.FindOne(ctx, bson.M{"id": objId}).Decode(&user)
if err != nil {
return c.JSON(http.StatusInternalServerError, responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
return c.JSON(http.StatusOK, responses.UserResponse{Status: http.StatusOK, Message: "success", Data: &echo.Map{"data": user}})
}
上面的代碼片段執行以下操作:
userId
從字符串類型轉換為MongoDB使用的BSON類型primitive.ObjectID
。使用userCollection.FindOne
方法搜索用戶,將轉換后的objId
作為過濾器傳遞,并使用attribute 方法來獲取相應的用戶對象。最后,我們返回解碼后的響應。接下來,我們需要使用路由 API URL 和相應的控制器進行更新,如下所示:
package routes
import (
//import goes here
)
func UserRoute(e *echo.Echo) {
//other routes goes here
e.GET("/user/:userId", controllers.GetAUser) //add this
}
PS: 我們還向URL路徑傳遞了一個userid參數。這個指定的參數必須與我們在控制器中指定的參數相匹配。
編輯用戶端點
為了編輯用戶,我們需要按照下面的方式修改user_controller.go
文件:
package controllers
import (
//other import goes here
)
var userCollection *mongo.Collection = configs.GetCollection(configs.DB, "users")
var validate = validator.New()
func CreateUser(c echo.Context) error {
//create user code goes here
}
func GetAUser(c echo.Context) error {
//get a user code goes here
}
func EditAUser(c echo.Context) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
userId := c.Param("userId")
var user models.User
defer cancel()
objId, _ := primitive.ObjectIDFromHex(userId)
//validate the request body
if err := c.Bind(&user); err != nil {
return c.JSON(http.StatusBadRequest, responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
//use the validator library to validate required fields
if validationErr := validate.Struct(&user); validationErr != nil {
return c.JSON(http.StatusBadRequest, responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &echo.Map{"data": validationErr.Error()}})
}
update := bson.M{"name": user.Name, "location": user.Location, "title": user.Title}
result, err := userCollection.UpdateOne(ctx, bson.M{"id": objId}, bson.M{"$set": update})
if err != nil {
return c.JSON(http.StatusInternalServerError, responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
//get updated user details
var updatedUser models.User
if result.MatchedCount == 1 {
err := userCollection.FindOne(ctx, bson.M{"id": objId}).Decode(&updatedUser)
if err != nil {
return c.JSON(http.StatusInternalServerError, responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
}
return c.JSON(http.StatusOK, responses.UserResponse{Status: http.StatusOK, Message: "success", Data: &echo.Map{"data": updatedUser}})
}
上述函數與CreateUser
函數的功能類似,但有所不同。在這個函數中,我們引入了一個update
變量,用于獲取需要更新的字段,并使用.UpdateOne
方法更新了集合中的記錄。最后,我們搜索了更新后的用戶詳情,并返回了解碼后的響應。
接下來,我們需要使用路由 API URL 和相應的控制器更新user_routes.go
文件,如下所示:
package routes
import (
//import goes here
)
func UserRoute(e *echo.Echo) {
//other routes goes here
e.PUT("/user/:userId", controllers.EditAUser) //add this
}
刪除用戶終端節點
要刪除一個用戶,我們需要修改user_controller.go
文件,如下:
package controllers
import (
//other import goes here
)
var userCollection *mongo.Collection = configs.GetCollection(configs.DB, "users")
var validate = validator.New()
func CreateUser(c echo.Context) error {
//create user code goes here
}
func GetAUser(c echo.Context) error {
//get a user code goes here
}
func EditAUser(c echo.Context) error {
//edit a user code goes here
}
func DeleteAUser(c echo.Context) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
userId := c.Param("userId")
defer cancel()
objId, _ := primitive.ObjectIDFromHex(userId)
result, err := userCollection.DeleteOne(ctx, bson.M{"id": objId})
if err != nil {
return c.JSON(http.StatusInternalServerError, responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
if result.DeletedCount < 1 {
return c.JSON(http.StatusNotFound, responses.UserResponse{Status: http.StatusNotFound, Message: "error", Data: &echo.Map{"data": "User with specified ID not found!"}})
}
return c.JSON(http.StatusOK, responses.UserResponse{Status: http.StatusOK, Message: "success", Data: &echo.Map{"data": "User successfully deleted!"}})
}
該函數按照前面的步驟操作,我們還檢查了項目是否已成功刪除并返回相應的響應。
接下來,我們需要使用路由 API URL 和相應的控制器更新user_routes.go
文件,如下所示:
package routes
import (
//import goes here
)
func UserRoute(e *echo.Echo) {
//other routes goes here
e.DELETE("/user/:userId", controllers.DeleteAUser) //add this
}
獲取用戶列表端點
要獲取用戶列表,我們需要修改user_controller.go
文件,如下:
package controllers
import (
//other import goes here
)
var userCollection *mongo.Collection = configs.GetCollection(configs.DB, "users")
var validate = validator.New()
func CreateUser(c echo.Context) error {
//create user code goes here
}
func GetAUser(c echo.Context) error {
//get a user code goes here
}
func EditAUser(c echo.Context) error {
//edit a user code goes here
}
func DeleteAUser(c echo.Context) error {
//delete a user code goes here
}
func GetAllUsers(c echo.Context) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
var users []models.User
defer cancel()
results, err := userCollection.Find(ctx, bson.M{})
if err != nil {
return c.JSON(http.StatusInternalServerError, responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
//reading from the db in an optimal way
defer results.Close(ctx)
for results.Next(ctx) {
var singleUser models.User
if err = results.Decode(&singleUser); err != nil {
return c.JSON(http.StatusInternalServerError, responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
users = append(users, singleUser)
}
return c.JSON(http.StatusOK, responses.UserResponse{Status: http.StatusOK, Message: "success", Data: &echo.Map{"data": users}})
}
該函數按照前面的步驟操作,我們還使用 attribute 方法以最佳方式讀取 retuned 列表,以遍歷返回的用戶列表。
接下來,我們需要使用路由 API URL 和相應的控制器更新user_routes.go
文件,如下所示:
package routes
import (
//import goes here
)
func UserRoute(e *echo.Echo) {
//other routes goes here
e.GET("/users", controllers.GetAllUsers) //add this
}
user_controller.go
package controllers
import (
"echo-mongo-api/configs"
"echo-mongo-api/models"
"echo-mongo-api/responses"
"net/http"
"time"
"github.com/go-playground/validator/v10"
"github.com/labstack/echo/v4"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"golang.org/x/net/context"
)
var userCollection *mongo.Collection = configs.GetCollection(configs.DB, "users")
var validate = validator.New()
func CreateUser(c echo.Context) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
var user models.User
defer cancel()
//validate the request body
if err := c.Bind(&user); err != nil {
return c.JSON(http.StatusBadRequest, responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
//use the validator library to validate required fields
if validationErr := validate.Struct(&user); validationErr != nil {
return c.JSON(http.StatusBadRequest, responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &echo.Map{"data": validationErr.Error()}})
}
newUser := models.User{
Id: primitive.NewObjectID(),
Name: user.Name,
Location: user.Location,
Title: user.Title,
}
result, err := userCollection.InsertOne(ctx, newUser)
if err != nil {
return c.JSON(http.StatusInternalServerError, responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
return c.JSON(http.StatusCreated, responses.UserResponse{Status: http.StatusCreated, Message: "success", Data: &echo.Map{"data": result}})
}
func GetAUser(c echo.Context) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
userId := c.Param("userId")
var user models.User
defer cancel()
objId, _ := primitive.ObjectIDFromHex(userId)
err := userCollection.FindOne(ctx, bson.M{"id": objId}).Decode(&user)
if err != nil {
return c.JSON(http.StatusInternalServerError, responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
return c.JSON(http.StatusOK, responses.UserResponse{Status: http.StatusOK, Message: "success", Data: &echo.Map{"data": user}})
}
func EditAUser(c echo.Context) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
userId := c.Param("userId")
var user models.User
defer cancel()
objId, _ := primitive.ObjectIDFromHex(userId)
//validate the request body
if err := c.Bind(&user); err != nil {
return c.JSON(http.StatusBadRequest, responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
//use the validator library to validate required fields
if validationErr := validate.Struct(&user); validationErr != nil {
return c.JSON(http.StatusBadRequest, responses.UserResponse{Status: http.StatusBadRequest, Message: "error", Data: &echo.Map{"data": validationErr.Error()}})
}
update := bson.M{"name": user.Name, "location": user.Location, "title": user.Title}
result, err := userCollection.UpdateOne(ctx, bson.M{"id": objId}, bson.M{"$set": update})
if err != nil {
return c.JSON(http.StatusInternalServerError, responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
//get updated user details
var updatedUser models.User
if result.MatchedCount == 1 {
err := userCollection.FindOne(ctx, bson.M{"id": objId}).Decode(&updatedUser)
if err != nil {
return c.JSON(http.StatusInternalServerError, responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
}
return c.JSON(http.StatusOK, responses.UserResponse{Status: http.StatusOK, Message: "success", Data: &echo.Map{"data": updatedUser}})
}
func DeleteAUser(c echo.Context) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
userId := c.Param("userId")
defer cancel()
objId, _ := primitive.ObjectIDFromHex(userId)
result, err := userCollection.DeleteOne(ctx, bson.M{"id": objId})
if err != nil {
return c.JSON(http.StatusInternalServerError, responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
if result.DeletedCount < 1 {
return c.JSON(http.StatusNotFound, responses.UserResponse{Status: http.StatusNotFound, Message: "error", Data: &echo.Map{"data": "User with specified ID not found!"}})
}
return c.JSON(http.StatusOK, responses.UserResponse{Status: http.StatusOK, Message: "success", Data: &echo.Map{"data": "User successfully deleted!"}})
}
func GetAllUsers(c echo.Context) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
var users []models.User
defer cancel()
results, err := userCollection.Find(ctx, bson.M{})
if err != nil {
return c.JSON(http.StatusInternalServerError, responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
//reading from the db in an optimal way
defer results.Close(ctx)
for results.Next(ctx) {
var singleUser models.User
if err = results.Decode(&singleUser); err != nil {
return c.JSON(http.StatusInternalServerError, responses.UserResponse{Status: http.StatusInternalServerError, Message: "error", Data: &echo.Map{"data": err.Error()}})
}
users = append(users, singleUser)
}
return c.JSON(http.StatusOK, responses.UserResponse{Status: http.StatusOK, Message: "success", Data: &echo.Map{"data": users}})
}
user_route.go
package routes
import (
"echo-mongo-api/controllers"
"github.com/labstack/echo/v4"
)
func UserRoute(e *echo.Echo) {
e.POST("/user", controllers.CreateUser)
e.GET("/user/:userId", controllers.GetAUser)
e.PUT("/user/:userId", controllers.EditAUser)
e.DELETE("/user/:userId", controllers.DeleteAUser)
e.GET("/users", controllers.GetAllUsers)
}
完成后,我們可以通過在終端中運行以下命令來啟動開發服務器來測試我們的應用程序。
go run main.go
本文探討了如何利用 MongoDB 構建 Echo 應用程序、開發 REST API 以及實現數據的持久化保存。
您可能會發現以下資源對您有所幫助:
原文鏈接:https://medium.com/geekculture/build-a-rest-api-with-golang-and-mongodb-echo-version-be48eccdefe3