
使用这些基本 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