go api框架搭建

分类: go

主要涉及的内容:

  • API开发框架 gin-gonic
  • ORM框架 gorm
  • Go语言 mysql 驱动

依赖包

框架引入 gin

  1. $ go get github.com/gin-gonic/gin@latest
  2. $ go get -u github.com/jinzhu/gorm@latest
  3. $ go get github.com/go-sql-driver/mysql@latest

helloworld

  1. package main
  2. import "github.com/gin-gonic/gin"
  3. func main() {
  4. r := gin.Default()
  5. r.GET("/ping", func(c *gin.Context) {
  6. c.JSON(200, gin.H{
  7. "message": "pong",
  8. })
  9. })
  10. // listen and serve on 0.0.0.0:8080
  11. r.Run()
  12. }

路由设计

  1. package main
  2. import "github.com/gin-gonic/gin"
  3. var router = gin.Default()
  4. func init() {
  5. router := gin.Default()
  6. v1 := router.Group("/api/v1/todos")
  7. {
  8. v1.POST("/", createTodo)
  9. v1.GET("/", fetchAllTodo)
  10. v1.GET("/:id", fetchSingleTodo)
  11. v1.PUT("/:id", updateTodo)
  12. v1.DELETE("/:id", deleteTodo)
  13. }
  14. }

数据库设计

  1. drop database if exists demo;
  2. create database demo charset='utf8';
  3. use demo;
  4. drop table if exists todo;
  5. create table todo (
  6. primary key(id),
  7. id int not null auto_increment,
  8. title varchar(256) not null default '待办事项',
  9. completed bool not null default 0,
  10. created_at timestamp not null default current_timestamp,
  11. updated_at timestamp not null default current_timestamp,
  12. deleted_at timestamp not null default current_timestamp
  13. ) Engine=Innodb;

连接数据库

  1. package main
  2. import (
  3. "github.com/jinzhu/gorm"
  4. _ "github.com/jinzhu/gorm/dialects/mysql"
  5. )
  6. var (
  7. db *gorm.DB
  8. sqlConnection = "golang:1234567890@(114.115.136.205)/demo?charset=utf8&parseTime=True&loc=Local"
  9. )
  10. func init() {
  11. //打开数据库连接
  12. var err error
  13. db, err = gorm.Open("mysql", sqlConnection)
  14. if err != nil {
  15. panic("failed to connect database")
  16. }
  17. db.AutoMigrate(&todoModel{})
  18. }

模型设计

  1. package main
  2. import "github.com/jinzhu/gorm"
  3. type (
  4. // entity类
  5. todoModel struct {
  6. gorm.Model
  7. Title string `json:"title"`
  8. Completed int `json:"completed"`
  9. }
  10. // response entity
  11. transformedTodo struct {
  12. ID uint `json:"id"`
  13. Title string `json:"title"`
  14. Completed bool `json:"completed"`
  15. }
  16. )

CRUD

  1. package main
  2. import (
  3. "github.com/gin-gonic/gin"
  4. "strconv"
  5. "net/http"
  6. )
  7. // createTodo add a new todo
  8. func createTodo(c *gin.Context) {
  9. completed, _ := strconv.Atoi(c.PostForm("completed"))
  10. todo := todoModel{Title: c.PostForm("title"), Completed: completed}
  11. db.Save(&todo)
  12. c.JSON(http.StatusCreated, gin.H{"status": http.StatusCreated, "message": "Todo item created successfully!", "resourceId": todo.ID})
  13. }
  14. // fetchAllTodo fetch all todos
  15. func fetchAllTodo(c *gin.Context) {
  16. var todos []todoModel
  17. var _todos []transformedTodo
  18. db.Find(&todos)
  19. if len(todos) <= 0 {
  20. c.JSON(http.StatusNotFound, gin.H{"status": http.StatusNotFound, "message": "No todo found!"})
  21. return
  22. }
  23. //transforms the todos for building a good response
  24. for _, item := range todos {
  25. completed := false
  26. if item.Completed == 1 {
  27. completed = true
  28. } else {
  29. completed = false
  30. }
  31. _todos = append(_todos, transformedTodo{ID: item.ID, Title: item.Title, Completed: completed})
  32. }
  33. c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": _todos})
  34. }
  35. // fetchSingleTodo fetch a single todo
  36. func fetchSingleTodo(c *gin.Context) {
  37. var todo todoModel
  38. todoID := c.Param("id")
  39. db.First(&todo, todoID)
  40. if todo.ID == 0 {
  41. c.JSON(http.StatusNotFound, gin.H{"status": http.StatusNotFound, "message": "No todo found!"})
  42. return
  43. }
  44. completed := false
  45. if todo.Completed == 1 {
  46. completed = true
  47. } else {
  48. completed = false
  49. }
  50. _todo := transformedTodo{ID: todo.ID, Title: todo.Title, Completed: completed}
  51. c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": _todo})
  52. }
  53. // updateTodo update a todo
  54. func updateTodo(c *gin.Context) {
  55. var todo todoModel
  56. todoID := c.Param("id")
  57. db.First(&todo, todoID)
  58. if todo.ID == 0 {
  59. c.JSON(http.StatusNotFound, gin.H{"status": http.StatusNotFound, "message": "No todo found!"})
  60. return
  61. }
  62. db.Model(&todo).Update("title", c.PostForm("title"))
  63. completed, _ := strconv.Atoi(c.PostForm("completed"))
  64. db.Model(&todo).Update("completed", completed)
  65. c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "message": "Todo updated successfully!"})
  66. }
  67. // deleteTodo remove a todo
  68. func deleteTodo(c *gin.Context) {
  69. var todo todoModel
  70. todoID := c.Param("id")
  71. db.First(&todo, todoID)
  72. if todo.ID == 0 {
  73. c.JSON(http.StatusNotFound, gin.H{"status": http.StatusNotFound, "message": "No todo found!"})
  74. return
  75. }
  76. db.Delete(&todo)
  77. c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "message": "Todo deleted successfully!"})
  78. }

编译打包

将多个go文件打包为一个可执行文件

  1. go build main.go router.go controller.go config.go model.go

如果把所有的代码放在一个文件里面,直接运行即可go build main.go。

单元测试(略)

运维上线

  1. nohup ./main &
标签: go

上一篇: 没有了

下一篇: go vscode的settings.json配置

by 2023-08-07 23:49:08
篇笔记

学习笔记