当前位置: 首页 > 科技观察

Go:在MongoDB之上构建RESTAPI-FiberEdition

时间:2023-03-12 08:02:52 科技观察

大家好,我是ProgrammerSpectre。之前分享过一篇文章:《项目实战:使用 Fiber + Gorm 构建 REST API》,数据库用的是SQLite。今天分享一篇基于MongoDB构建RESTAPI的文章,依然使用Fiber框架。1、准备工作开始前,首先要准备好MongoDB。这里我们不自己安装MongoDB,而是使用云端。Mongo提供免费使用。配置MongoDB如果没有MongoDB账号,先注册一个:https://www.mongodb.com/zh-cn/cloud/atlas/register。如果你有一个帐户,你可以直接登录。然后新建一个项目(project):NewProject项目名,可以取一个自己喜欢的名字,比如golang-api,然后Next:输入项目名然后直接点击CreateProject:CreateProject然后点击BuildaDatabase:BuildaDatabase选择freeShared:Shared红色高亮点击CreateCluster创建集群,需要一定时间。(其他的可以使用默认的)创建集群然后需要创建一个可以访问数据库的用户。点击创建用户,如果需要保证安全,可以限制IP。然后单击完成并关闭。也可以不限制创建用户的IP,毕竟我们只是练习和测试项目。(如果运行下面的程序,发现无法连接MongoDB,可以考虑直接去掉IP限制)添加IP保存后,可以看到DatabaseDeployments界面:DatabaseScreenInitializetheGoprojectCreateaprojectonGitHub:fibermongo,clone到本地,然后初始化:$gomodinitgithub.com/programmerug/fibermongogo:creatingnewgo.mod:modulegithub.com/programmerug/fibermongo安装下面两个依赖:$goget-vgithub.com/gofiber/fiber/v2$goget-vgo.mongodb.org/mongo-driver/mongo然后在目录下创建main.go,输入以下内容:packagemainimport("github.com/gofiber/fiber/v2")funcmain(){app:=fiber.New()app.Get("/",func(c*fiber.Ctx)error{returnc.JSON(&fiber.Map{"welcome":"你好来自Fiber+MongoDB"})})app.Listen(":2022")}开始gorunmain.go,然后通过curlie[1]的测试(这是Go实现的一个curl-like工具,其易用性使用方式类似于httpie):$curl即localhost:2022HTTP/1.1200OKDate:Mon,07Feb202209:05:48GMTContent-Type:application/jsonContent-Length:40{"welcome":"HellofromFiber+MongoDB"}2.目录结构创建以下内容目录,注意注释:├──config项目配置文件├──应用逻辑控制器├──go.mod├──go.sum├──main.go├──数据和数据库模型逻辑├──回应用于描述我们希望API给的响应的文件└──路由用于URL模式和处理程序信息3.配置与MongoDB的连接为了让我们的程序连接到数据库MongoDB,类似于MySQL,连接字符串需要在上面MongoDB的DatabaseDeployments页面,点击Connect按钮:Connecttodatabase,然后点击Connectyourapplication,然后选择Goanditsversion作为驱动。connectapplication然后copy:CopyconnectionstringSetenvironmentvariables在项目根目录下创建一个.env文件,添加MONGOURI:MONGOURI=mongodb+srv://:@cluster0.k0oen.mongodb.net/myFirstDatabase?retryWrites=true&w=大多数注意替换用户和密码是你一开始设置的。然后你需要编写代码来读取环境变量。因为环境变量是以key=value的简单形式保存在文件中,所以我们使用对应的第三方库:github.com/joho/godotenv。在config目录下添加env.go文件,输入如下内容:呃!=nil{log.Fatal("Errorloading.envfile")}returnos.Getenv("MONGOURI")}然后执行gomodtidy来更新依赖。(该命令可多次执行)连接MongoDB,在config目录下创建setup.go文件,添加如下内容:packageconfigimport("context""fmt""log""time""go.mongodb.org/mongo-driver/mongo""go.mongodb.org/mongo-driver/mongo/options")funcConnectDB()*mongo.Client{client,err:=mongo.NewClient(options.Client().ApplyURI(EnvMongoURI()))iferr!=nil{log.Fatal(err)}ctx,_:=context.WithTimeout(context.Background(),10*time.Second)err=client.Connect(ctx)iferr!=nil{log.Fatal(err)}//ping数据库err=client.Ping(ctx,nil)iferr!=nil{log.Fatal(err)}fmt.Println("ConnectedtoMongoDB")returnclient}//MongoDBClient实例varDB*mongo.Client=ConnectDB()//GetCollection获取数据库集合funcGetCollection(client*mongo.Client,collectionNamestring)*mongo.Collection{collection:=client.Database("golangAPI").Collection(collectionName)returncollection}上面的代码简单解释一下:Imp调整所需的MongoDB依赖项创建一个ConnectDB函数,首先配置客户端使用正确的URI并检查错误。其次,我们定义了10秒的超时以在尝试连接时使用。第三,检查连接数据库是否有错误,超过10秒就取消连接。最后,我们ping数据库以测试我们的连接并返回客户端实例。调用ConnectDB创建一个DB变量实例。这在创建集合时会派上用场。创建一个GetCollection函数来获取集合。以上设计不是最好的,主要是让大家熟悉一下MongoDB的API。4.设置APIroutehandler和responsetypeRouteHandler完成后,我们需要在route文件夹下创建一个user_route.go文件来管理我们应用中所有用户相关的路由,如下:packageroutesimport"github.com/gofiber/fiber/v2"funcUserRoute(app*fiber.App){//所有与用户相关的路由都在这里}接下来修改main.go,路由到上面的函数进行处理:packagemainimport("github.com/gofiber/fiber/v2""github.com/programmerug/fibermongo/route")funcmain(){app:=fiber.New()//routesroute.UserRoute(app)app.Listen(":2022")}响应类型接下来,我们需要创建一个可重用的结构来描述我们API的响应。为此,在响应文件夹中创建一个user_response.go文件并添加以下内容:json:"message"`Datainterface{}`json:"data"`}上面的代码片段创建了一个通用响应类型:UserResponse。5.RESTAPI接下来,我们需要一个模型来表示我们的应用程序数据。为此,我们在模型中创建user_model.go文件并输入以下内容:packagemodelimport"go.mongodb.org/mongo-driver/bson/primitive"typeUserstruct{IDprimitive.ObjectID`json:"id,omitempty"`名称字符串`json:"name,omitempty"验证:"required"`位置字符串`json:"location,omitempty"验证:"required"`标题字符串`json:"title,omitempty"验证:"required"`}解释一下上面的标签:validate,这是github.com/go-playground/validator/v10库。创建用户端点模型就绪后,我们现在可以创建一个函数来创建用户。在控制器文件夹下创建文件user_controller.go并添加以下内容:packagecontrollerimport("context""net/http""time""github.com/programmerug/fibermongo/config""github.com/programmerug/fibermongo/model”“github.com/programmerug/fibermongo/response”“github.com/go-playground/validator/v10”“github.com/gofiber/fiber/v2”“go.mongodb.org/mongo-driver/bson/primitive""go.mongodb.org/mongo-driver/mongo")varuserCollection*mongo.Collection=config.GetCollection(config.DB,"user")varvalidate=validator.New()funcCreateUser(c*fiber.Ctx)error{ctx,cancel:=context.WithTimeout(context.Background(),10*time.Second)varusermodel.Userdefercancel()//验证请求体iferr:=c.BodyParser(&user);错误!=nil{returnc.Status(http.StatusBadRequest).JSON(response.UserResponse{Status:http.StatusBadRequest,Message:"error",Data:&fiber.Map{"data":err.Error()}})}//如果validationErr:=v使用验证器库来验证必填字段alidate.Struct(&用户);validationErr!=nil{returnc.Status(http.StatusBadRequest).JSON(response.UserResponse{Status:http.StatusBadRequest,Message:"error",Data:&fiber.Map{"data":validationErr.Error()}})}newUser:=model.User{ID:primitive.NewObjectID(),Name:user.Name,Location:user.Location,Title:user.Title,}结果,err:=userCollection。InsertOne(ctx,newUser)iferr!=nil{returnc.Status(http.StatusInternalServerError).JSON(response.UserResponse{Status:http.StatusInternalServerError,Message:“error”,Data:err.Error()})}returnc.Status(http.StatusCreated).JSON(response.UserResponse{Status:http.StatusCreated,Message:"success",Data:result})}这段代码有很多代码,简单说明一下:首先,导入相关依赖在config中通过GetCollection函数创建userCollection通过github.com/go-playground/validator/v10获取validator验证器在CreateUser函数中,我们首先定义了一个向文档插入用户时的10秒超时时间,并使用用于验证请求的验证器库文本和必填字段包装在UserResponse中,如果有错误则返回适当的消息和状态代码。其次,我们创建一个newUser变量,使用userCollection.InsertOne函数插入它并检查错误。最后,如果插入成功,我们返回正确的响应。然后在user_route.go文件中绑定APIURL和对应的handler:){app.Post("/user",controller.CreateUser)}gorunmain.go启动程序,无一例外会看到如下输出:$gorunmain.goConnectedtoMongoDB┌────────────────────────────────────────────────────────────┐│Fiberv2.26.0││http://127.0.0.1:2022││(绑定在主机0.0.0.0和端口2022上)││││处理程序............1进程。.............1││Prefork......禁用PID.........7158│└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘然后通过curlie测试创建用户:$curliePOST-d'{"name":"Ghost","location":"Beijing","title":"SoftwareEngineer"}'http://localhost:2022/user将看到以下输出:HTTP/1.1201CreatedDate:Tue,08Feb202203:08:17GMTContent-Type:application/jsonContent-Length:92{"status":201,"message":"success","data":{"InsertedID":"6201de338ecf6d62fb799d62"}}然后就可以去MongoDB中确认数据是否写入了:insertoneand其他操作接下来就是实现内容的查找、更新、删除,这里不一一赘述,只列出关键代码。先看完整的路由:",controller.CreateUser)app.Get("/user/:userId",controller.GetAUser)app.Put("/user/:userId",controller.EditAUser)app.Delete("/user/:userId",controller.DeleteAUser)app.Get("/users",controller.GetAllUsers)}通过userId获取用户信息,因为userId是字符串,需要转成BSON的objectID。MongoDB库有一个特殊的函数:objId,_:=primitive.ObjectIDFromHex(userId)具体操作MongoDB的API可以参考文档:https://pkg.go.dev/go.mongodb.org/mongo-司机/蒙戈。6.结语本文主要是带领大家完成一个基本的CRUD工作,让大家熟悉Fiber+MongoDB构建RESTfulAPI,熟悉工作流程。同时了解相关库的使用。本文完整代码见:https://github.com/programmerug/fibermongo。参考文章:https://dev.to/hackmamba/build-a-rest-api-with-golang-and-mongodb-fiber-version-4la0另外,在测试API的时候,可以使用自己喜欢的工具,比如作为邮递员。参考文献[1]curlie:https://curlie.io/本文转载自微信公众号“鬼”,可通过以下二维码关注。转载本文请联系有鬼公众号。