主要涉及的内容:
- API开发框架
gin-gonic - ORM框架
gorm - Go语言
mysql驱动
依赖包
框架引入 gin
$ go get github.com/gin-gonic/gin@latest$ go get -u github.com/jinzhu/gorm@latest$ go get github.com/go-sql-driver/mysql@latest
helloworld
package mainimport "github.com/gin-gonic/gin"func main() {r := gin.Default()r.GET("/ping", func(c *gin.Context) {c.JSON(200, gin.H{"message": "pong",})})// listen and serve on 0.0.0.0:8080r.Run()}
路由设计
package mainimport "github.com/gin-gonic/gin"var router = gin.Default()func init() {router := gin.Default()v1 := router.Group("/api/v1/todos"){v1.POST("/", createTodo)v1.GET("/", fetchAllTodo)v1.GET("/:id", fetchSingleTodo)v1.PUT("/:id", updateTodo)v1.DELETE("/:id", deleteTodo)}}
数据库设计
drop database if exists demo;create database demo charset='utf8';use demo;drop table if exists todo;create table todo (primary key(id),id int not null auto_increment,title varchar(256) not null default '待办事项',completed bool not null default 0,created_at timestamp not null default current_timestamp,updated_at timestamp not null default current_timestamp,deleted_at timestamp not null default current_timestamp) Engine=Innodb;
连接数据库
package mainimport ("github.com/jinzhu/gorm"_ "github.com/jinzhu/gorm/dialects/mysql")var (db *gorm.DBsqlConnection = "golang:1234567890@(114.115.136.205)/demo?charset=utf8&parseTime=True&loc=Local")func init() {//打开数据库连接var err errordb, err = gorm.Open("mysql", sqlConnection)if err != nil {panic("failed to connect database")}db.AutoMigrate(&todoModel{})}
模型设计
package mainimport "github.com/jinzhu/gorm"type (// entity类todoModel struct {gorm.ModelTitle string `json:"title"`Completed int `json:"completed"`}// response entitytransformedTodo struct {ID uint `json:"id"`Title string `json:"title"`Completed bool `json:"completed"`})
CRUD
package mainimport ("github.com/gin-gonic/gin""strconv""net/http")// createTodo add a new todofunc createTodo(c *gin.Context) {completed, _ := strconv.Atoi(c.PostForm("completed"))todo := todoModel{Title: c.PostForm("title"), Completed: completed}db.Save(&todo)c.JSON(http.StatusCreated, gin.H{"status": http.StatusCreated, "message": "Todo item created successfully!", "resourceId": todo.ID})}// fetchAllTodo fetch all todosfunc fetchAllTodo(c *gin.Context) {var todos []todoModelvar _todos []transformedTododb.Find(&todos)if len(todos) <= 0 {c.JSON(http.StatusNotFound, gin.H{"status": http.StatusNotFound, "message": "No todo found!"})return}//transforms the todos for building a good responsefor _, item := range todos {completed := falseif item.Completed == 1 {completed = true} else {completed = false}_todos = append(_todos, transformedTodo{ID: item.ID, Title: item.Title, Completed: completed})}c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": _todos})}// fetchSingleTodo fetch a single todofunc fetchSingleTodo(c *gin.Context) {var todo todoModeltodoID := c.Param("id")db.First(&todo, todoID)if todo.ID == 0 {c.JSON(http.StatusNotFound, gin.H{"status": http.StatusNotFound, "message": "No todo found!"})return}completed := falseif todo.Completed == 1 {completed = true} else {completed = false}_todo := transformedTodo{ID: todo.ID, Title: todo.Title, Completed: completed}c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "data": _todo})}// updateTodo update a todofunc updateTodo(c *gin.Context) {var todo todoModeltodoID := c.Param("id")db.First(&todo, todoID)if todo.ID == 0 {c.JSON(http.StatusNotFound, gin.H{"status": http.StatusNotFound, "message": "No todo found!"})return}db.Model(&todo).Update("title", c.PostForm("title"))completed, _ := strconv.Atoi(c.PostForm("completed"))db.Model(&todo).Update("completed", completed)c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "message": "Todo updated successfully!"})}// deleteTodo remove a todofunc deleteTodo(c *gin.Context) {var todo todoModeltodoID := c.Param("id")db.First(&todo, todoID)if todo.ID == 0 {c.JSON(http.StatusNotFound, gin.H{"status": http.StatusNotFound, "message": "No todo found!"})return}db.Delete(&todo)c.JSON(http.StatusOK, gin.H{"status": http.StatusOK, "message": "Todo deleted successfully!"})}
编译打包
将多个go文件打包为一个可执行文件
go build main.go router.go controller.go config.go model.go
如果把所有的代码放在一个文件里面,直接运行即可go build main.go。
单元测试(略)
运维上线
nohup ./main &