Gin框架与《Web Development with Go》实践(七)

与Mongodb有关的数据持久

taskmanager2项目中的目录结构:


Gin框架与《Web Development with Go》实践(七)_第1张图片
taskmaanger-data2.png

src/taskmanager2/data2/taskRepository.go
其中的内容为与mongodb中的集合task紧密相关的CRUD操作

package data2

import (
    "time"
    "gopkg.in/mgo.v2"
    "gopkg.in/mgo.v2/bson"
    "taskmanager2/models2"
)

type TaskRepository struct {
    C *mgo.Collection
}

func (r *TaskRepository) Create(task *models2.Task) error {
    obj_id := bson.NewObjectId()
    task.Id = obj_id
    task.CreatedOn = time.Now()
    task.Status = "Created"
    err := r.C.Insert(&task)
    return err
}

func (r *TaskRepository) Update(task *models2.Task) error {
    // partial update on MogoDB
    err := r.C.Update(bson.M{"_id": task.Id},
        bson.M{"$set": bson.M{
            "name":        task.Name,
            "description": task.Description,
            "due":         task.Due,
            "status":      task.Status,
            "tags":        task.Tags,
        }})
    return err
}
func (r *TaskRepository) Delete(id string) error {
    err := r.C.Remove(bson.M{"_id": bson.ObjectIdHex(id)})
    return err
}
func (r *TaskRepository) GetAll() []models2.Task {
    var tasks []models2.Task
    iter := r.C.Find(nil).Iter()
    result := models2.Task{}
    for iter.Next(&result) {
        tasks = append(tasks, result)
    }
    return tasks
}
func (r *TaskRepository) GetById(id string) (task models2.Task, err error) {
    err = r.C.FindId(bson.ObjectIdHex(id)).One(&task)
    return
}
func (r *TaskRepository) GetByUser(user string) []models2.Task {
    var tasks []models2.Task
    iter := r.C.Find(bson.M{"createdby": user}).Iter()
    result := models2.Task{}
    for iter.Next(&result) {
        tasks = append(tasks, result)
    }
    return tasks
}

task资源的处理函数

Gin框架与《Web Development with Go》实践(七)_第2张图片

资源路径与其对应的处理函数:
src/taskmanager2/routers2/task.go

package routers2

import (
    "gopkg.in/gin-gonic/gin.v1"
    "taskmanager2/controllers2"
    "taskmanager2/common2"
)

// SetTaskRoutes configures routes for task entity
func SetTaskRoutes(router *gin.Engine) *gin.Engine {

    taR := router.Group("/tm2/tasks")
    taR.Use(common2.Authorize())
    {
        taR.POST("", controllers2.CreateTask)
        taR.PUT(":id", controllers2.UpdateTask)
        taR.DELETE(":id", controllers2.DeleteTask)
        taR.GET("", controllers2.GetTasks)
        taR.GET("t/:id/", controllers2.GetTaskByID)
        taR.GET("users/:email/", controllers2.GetTasksByUser)
    }
    return router
}

具体函数:

Gin框架与《Web Development with Go》实践(七)_第3张图片

src/taskmanager2/controllers2/taskCtrler.go

package controllers2

import (
    "net/http"
    "gopkg.in/mgo.v2"
    "gopkg.in/mgo.v2/bson"
    "gopkg.in/gin-gonic/gin.v1"
    "taskmanager2/common2"
    "taskmanager2/data2"
)

// CreateTask insert a new Task document
// Handler for HTTP Post - "/tasks
func CreateTask(c *gin.Context) {
    var dataResource TaskResource
    // Decode the incoming Task json
    err := c.BindJSON(&dataResource)
    if err != nil {
        common2.DisplayAppError(
            c,
            err,
            "Invalid Task data",
            500,
        )
        return
    }
    task := &dataResource.Data
    context := NewContext()
    defer context.Close()
    context.User = task.CreatedBy

    col := context.DbCollection("tasks")
    repo := &data2.TaskRepository{C: col}

    // Insert a task document
    repo.Create(task)

    c.JSON(http.StatusCreated, TaskResource{Data: *task})
}

// GetTasks returns all Task document
// Handler for HTTP Get - "/tasks"
func GetTasks(c *gin.Context) {
    context := NewContext()
    defer context.Close()
    col := context.DbCollection("tasks")
    repo := &data2.TaskRepository{C: col}
    tasks := repo.GetAll()

    c.JSON(http.StatusOK, TasksResource{Data: tasks})
}

// GetTaskByID returns a single Task document by id
// Handler for HTTP Get - "/tasks/t/:id"
func GetTaskByID(c *gin.Context) {
    // Get id from the incoming url
    id := c.Param("id")
    context := NewContext()
    defer context.Close()

    col := context.DbCollection("tasks")
    repo := &data2.TaskRepository{C: col}
    task, err := repo.GetById(id)
    if err != nil {
        if err == mgo.ErrNotFound {
            c.JSON(http.StatusNoContent, gin.H{})

        } else {
            common2.DisplayAppError(
                c,
                err,
                "An unexpected error has occurred",
                500,
            )

        }
        return
    }
    c.JSON(http.StatusOK, TaskResource{Data: task})
}

// GetTasksByUser returns all Tasks created by a User
// Handler for HTTP Get - "/tasks/users/:email"
func GetTasksByUser(c *gin.Context) {
    // Get id from the incoming url
    user := c.Param("email")
    context := NewContext()
    defer context.Close()
    col := context.DbCollection("tasks")
    repo := &data2.TaskRepository{C: col}
    tasks := repo.GetByUser(user)

    c.JSON(http.StatusOK, TasksResource{Data: tasks})
}

// UpdateTask update an existing Task document
// Handler for HTTP Put - "/tasks/:id"
func UpdateTask(c *gin.Context) {
    // Get id from the incoming url
    id := bson.ObjectIdHex(c.Param("id"))
    var dataResource TaskResource
    // Decode the incoming Task json
    err := c.BindJSON(&dataResource)
    if err != nil {
        common2.DisplayAppError(
            c,
            err,
            "Invalid Task data",
            500,
        )
        return
    }
    task := &dataResource.Data
    task.Id = id
    context := NewContext()
    defer context.Close()
    col := context.DbCollection("tasks")
    repo := &data2.TaskRepository{C: col}
    // Update an existing Task document
    if err := repo.Update(task); err != nil {
        common2.DisplayAppError(
            c,
            err,
            "An unexpected error has occurred",
            500,
        )
        return
    }
    c.Status(http.StatusNoContent)
}

// DeleteTask deelete an existing Task document
// Handler for HTTP Delete - "/tasks/:id"
func DeleteTask(c *gin.Context) {

    id := c.Param("id")
    context := NewContext()
    defer context.Close()
    col := context.DbCollection("tasks")
    repo := &data2.TaskRepository{C: col}
    // Delete an existing Task document
    err := repo.Delete(id)
    if err != nil {
        common2.DisplayAppError(
            c,
            err,
            "An unexpected error has occurred",
            500,
        )
        return
    }
    c.Status(http.StatusNoContent)
}

json资源模型

src/taskmanager2/controllers2/resources.go

package controllers2

import (
    "taskmanager2/models2"
)

type (
    ...
    TaskResource struct {
        Data models2.Task `json:"data"`
    }
    TasksResource struct {
        Data []models2.Task `json:"data"`
    }
    ...
)

task资源的测试API操作

登录系统并获取jwt

post --- localhost:8890/tm2/users/login
调用:


Gin框架与《Web Development with Go》实践(七)_第4张图片

响应:


Gin框架与《Web Development with Go》实践(七)_第5张图片
增加数据

post --- localhost:8890/tm2/tasks/
调用:


Gin框架与《Web Development with Go》实践(七)_第6张图片

响应:


Gin框架与《Web Development with Go》实践(七)_第7张图片

数据库中查看结果:


Gin框架与《Web Development with Go》实践(七)_第8张图片
删除数据

delete --- localhost:8890/tm2/tasks/593e72625a9c4078ae5f1a79
调用:


Gin框架与《Web Development with Go》实践(七)_第9张图片

响应:


数据库中查看结果(第14条数据已被删除):


Gin框架与《Web Development with Go》实践(七)_第10张图片
修改数据

put --- localhost:8890/tm2/tasks/593e72495a9c4078ae5f1a78
调用:


Gin框架与《Web Development with Go》实践(七)_第11张图片

响应:


tm-p2.png

数据库中查看结果:
原数据:


Gin框架与《Web Development with Go》实践(七)_第12张图片

新数据:


Gin框架与《Web Development with Go》实践(七)_第13张图片
获取全部的数据

get --- localhost:8890/tm2/tasks
调用:


Gin框架与《Web Development with Go》实践(七)_第14张图片

响应:


Gin框架与《Web Development with Go》实践(七)_第15张图片
通过task的id获取数据

get --- localhost:8890/tm2/tasks/t/593e6f985a9c4078ae5f1a77/
调用:


Gin框架与《Web Development with Go》实践(七)_第16张图片

响应:


Gin框架与《Web Development with Go》实践(七)_第17张图片
通过user的email获取数据

get --- localhost:8890/tm2/tasks/users/[email protected]
调用:

Gin框架与《Web Development with Go》实践(七)_第18张图片

响应:


Gin框架与《Web Development with Go》实践(七)_第19张图片

小结

至此,RESTful API中,user和task资源的功能已全部实现。实践证明gin框架能够很好地满足此应用的改造要求。
在改造的过程中,某些细节之处仍有不足,待日后慢慢完善。

你可能感兴趣的:(Gin框架与《Web Development with Go》实践(七))