您的位置 首页 > 数码极客

golang如何获取restful风格的id

(原文作者:Saddam H)

今天,我将使用golang编程语言为一个todo应用构建一个简单的API 。我将使用golang最简单/最快的框架gin-gonic和一个漂亮的ORM gorm来进行数据库工作。要安装这些软件包,请进入工作区$GOPATH/src并在下面运行以下命令:

$ go get go $ go get -u gi $ go get gi

一个通用crud应用程序中,我们需要以下API:

  1. POST todos/
  2. GET todos/
  3. GET todos/{id}
  4. PUT todos/{id}
  5. DELETE todos/{id}

让我们开始编码,转到$GOPATH/src并创建一个目录。在todo目录中,创建一个文件main.go。将“gin framework”导入到我们的项目中,并在内部main函数中创建如下所示的路由。我喜欢添加api的前缀,例如“api/v1/”,这就是为什么我们将使用路由器Group方法的原因

包主要 导入( “ gi” )func main(){路由器:= gin.Default()v1:= rou(“ / api / v1 / todos”) { v1.POST(“ /”,createTodo) v1.GET(“ /”,fetchAllTodo) v1.GET(“ /:id”,fetchSingleTodo) v1 .PUT(“ /:id”,updateTodo) v1.DELETE(“ /:id”,deleteTodo) } rou()}

我们已经创建了5条路线,它们处理诸如createTodo, fetchAllTodo etc之类的某些功能。我们将很快对其进行讨论。

现在我们需要建立一个数据库连接。要使用数据库,请在我们的代码中拉gorm包和mysql方言。请遵循以下代码:

包装主要 进口( “gi” “gi” _ “gi/dialects/mysql” ) 变种DB * gorm.DBfunc init(){ //打开数据库连接 var err error db,err = gorm.Open(“ mysql”,“ root:12345 @ / demo?charset = utf8&parseTime = True&loc = Local”) 如果err!= nil { 恐慌(“连接数据库失败”) }//迁移架构 db.AutoMigrate(&todoModel {}) }

在上面的代码中,“ mysql”是我们的数据库驱动程序,“ root”是数据库用户名,“ 12345”密码和“ demo”是数据库名称。请根据需要更改这些信息。

我们将使用数据库功能来获取数据库连接。在让todoModel 和transformedTodo结构体。第一个结构将代表原始的Todo,第二个结构将保留转换后的todo以响应api。在这里,我们转换了todo响应,因为我们没有向使用者公开某些数据库字段(updated_at,created_at)。

type ( // todoModel describes a todoModel type todoModel struct { gorm.Model Title string `json:"title"` Completed int `json:"completed"` } // transformedTodo represents a formatted todo transformedTodo struct { ID uint `json:"id"` Title string `json:"title"` Completed bool `json:"completed"` } )

Todo struct还有一个字段gorm.Model,这意味着什么?好吧,该字段将为我们嵌入一个Model结构,其中包含四个字段“ ID,CreatedAt,UpdatedAt和DeletedAt”

Gorm具有迁移功能,我们已经在init功能中使用了它。当我们首先运行该应用程序时,它将创建一个连接,然后进行迁移。

//Migrate the schema db.AutoMigrate(&todoModel{})

使用phpmyadmin

您还记得我们在一分钟前写的五条路线吗?让我们一一实现五种方法。

当用户将带有“标题和完成的”字段的POST请求发送到路径“api/v1/todos/”时,它将由此路由处理 v1.POST(“/”, createTodo)

让我们实现createTodo函数

// createTodo add a new todo func createTodo(c *gin.Context) { completed, _ := ("completed")) todo := todoModel{Title: c.PostForm("title"), Completed: completed} db.Save(&todo) c.JSON, gin.H{"status": , "message": "Todo item created successfully!", "resourceId": }) }

在上面的代码中,我们使用gin Context接收发布的数据,并使用gorm数据库连接保存待办事项。保存资源后,我们会向resource id用户发送具有良好意义的回复。

让我们实现其余功能

// fetchAllTodo fetch all todos func fetchAllTodo(c *gin.Context) { var todos []todoModel var _todos []transformedTodo db.Find(&todos) if len(todos) <= 0 { c.JSON, gin.H{"status": , "message": "No todo found!"}) return } //transforms the todos for building a good response for _, item := range todos { completed := false if i == 1 { completed = true } else { completed = false } _todos = append(_todos, transformedTodo{ID: i, Title: i, Completed: completed}) } c.JSON, gin.H{"status": , "data": _todos}) } // fetchSingleTodo fetch a single todo func fetchSingleTodo(c *gin.Context) { var todo todoModel todoID := c.Param("id") db.First(&todo, todoID) if == 0 { c.JSON, gin.H{"status": , "message": "No todo found!"}) return } completed := false if == 1 { completed = true } else { completed = false } _todo := transformedTodo{ID: , Title: , Completed: completed} c.JSON, gin.H{"status": , "data": _todo}) } // updateTodo update a todo func updateTodo(c *gin.Context) { var todo todoModel todoID := c.Param("id") db.First(&todo, todoID) if == 0 { c.JSON, gin.H{"status": , "message": "No todo found!"}) return } db.Model(&todo).Update("title", c.PostForm("title")) completed, _ := ("completed")) db.Model(&todo).Update("completed", completed) c.JSON, gin.H{"status": , "message": "Todo updated successfully!"}) } // deleteTodo remove a todo func deleteTodo(c *gin.Context) { var todo todoModel todoID := c.Param("id") db.First(&todo, todoID) if == 0 { c.JSON, gin.H{"status": , "message": "No todo found!"}) return } db.Delete(&todo) c.JSON, gin.H{"status": , "message": "Todo deleted successfully!"}) }

在fetchAllTodo函数中,我们获取了所有待办事项,并使用构造了转换后的响应id, title, completed。我们删除了CreatedAt,UpdatedAt和DeletedAt字段,并将整数值转换为bool。

好吧,我们编写了足够的代码,让我们尝试构建应用程序并对其进行测试,我将使用chrome扩展程序Postman对其进行测试(您可以使用curl等任何REST客户端进行测试)。

要构建应用,请打开您的终端并进入项目目录

$ go build main.go

该命令将生成一个二进制文件,main并使用此命令运行该文件$ ./main。哇,我们简单的待办事项应用程序正在端口8080上运行。它将显示调试日志,因为默认情况下gin以调试模式和端口8080运行。

要测试api,请运行postman并依次测试api

创建一个待办事项


获取所有待办

获取一个待办事项

更新待办事项

删除待办事项

需要完整的源代码吗?

package main import ( "net/http" "strconv" "gi" "gi" _ "gi/dialects/mysql" ) var db *gorm.DB func init() { //open a db connection var err error db, err = gorm.Open("mysql", "root:12345@/demo?charset=utf8&parseTime=True&loc=Local") if err != nil { panic("failed to connect database") } //Migrate the schema db.AutoMigrate(&todoModel{}) } func main() { router := gin.Default() v1 := rou("/api/v1/todos") { v1.POST("/", createTodo) v1.GET("/", fetchAllTodo) v1.GET("/:id", fetchSingleTodo) v1.PUT("/:id", updateTodo) v1.DELETE("/:id", deleteTodo) } rou() } type ( // todoModel describes a todoModel type todoModel struct { gorm.Model Title string `json:"title"` Completed int `json:"completed"` } // transformedTodo represents a formatted todo transformedTodo struct { ID uint `json:"id"` Title string `json:"title"` Completed bool `json:"completed"` } ) // createTodo add a new todo func createTodo(c *gin.Context) { completed, _ := ("completed")) todo := todoModel{Title: c.PostForm("title"), Completed: completed} db.Save(&todo) c.JSON, gin.H{"status": , "message": "Todo item created successfully!", "resourceId": }) } // fetchAllTodo fetch all todos func fetchAllTodo(c *gin.Context) { var todos []todoModel var _todos []transformedTodo db.Find(&todos) if len(todos) <= 0 { c.JSON, gin.H{"status": , "message": "No todo found!"}) return } //transforms the todos for building a good response for _, item := range todos { completed := false if i == 1 { completed = true } else { completed = false } _todos = append(_todos, transformedTodo{ID: i, Title: i, Completed: completed}) } c.JSON, gin.H{"status": , "data": _todos}) } // fetchSingleTodo fetch a single todo func fetchSingleTodo(c *gin.Context) { var todo todoModel todoID := c.Param("id") db.First(&todo, todoID) if == 0 { c.JSON, gin.H{"status": , "message": "No todo found!"}) return } completed := false if == 1 { completed = true } else { completed = false } _todo := transformedTodo{ID: , Title: , Completed: completed} c.JSON, gin.H{"status": , "data": _todo}) } // updateTodo update a todo func updateTodo(c *gin.Context) { var todo todoModel todoID := c.Param("id") db.First(&todo, todoID) if == 0 { c.JSON, gin.H{"status": , "message": "No todo found!"}) return } db.Model(&todo).Update("title", c.PostForm("title")) completed, _ := ("completed")) db.Model(&todo).Update("completed", completed) c.JSON, gin.H{"status": , "message": "Todo updated successfully!"}) } // deleteTodo remove a todo func deleteTodo(c *gin.Context) { var todo todoModel todoID := c.Param("id") db.First(&todo, todoID) if == 0 { c.JSON, gin.H{"status": , "message": "No todo found!"}) return } db.Delete(&todo) c.JSON, gin.H{"status": , "message": "Todo deleted successfully!"}) }

注意:使用代码生产时,必须注意以下步骤:

  1. 不获取所有数据select * from todos,使用分页
  2. 不信任用户输入。您必须验证输入,有几种工具可以验证输入。阅读(https://medium.com/@thedevsaddam/an-easy-way-to-validate-go-request-c15182fd11b1)有关验证过程的文章
  3. 检查所有可能的错误
  4. 您应该根据需要使用日志记录和身份验证

我为我真的很抱歉BAD 英语和写作流程。如果您发现文章中有任何错误,请随时发表评论。

如果您发现文章有帮助,请在中关注我)

喜欢这篇文章吗?阅读另一篇有趣的文章:如何使用Go(lang)访问深度嵌套的JSON数据?

原文:https://thedevsaddam.medium.com/build-restful-api-service-in-golang-using-gin-gonic-framework-85b1a6e176f3

责任编辑: 鲁达

1.内容基于多重复合算法人工智能语言模型创作,旨在以深度学习研究为目的传播信息知识,内容观点与本网站无关,反馈举报请
2.仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证;
3.本站属于非营利性站点无毒无广告,请读者放心使用!

“golang如何获取restful风格的id”边界阅读