Gin框架與《Web Development with Go》實(shí)踐(七)

與Mongodb有關(guān)的數(shù)據(jù)持久

taskmanager2項(xiàng)目中的目錄結(jié)構(gòu):


taskmaanger-data2.png

src/taskmanager2/data2/taskRepository.go
其中的內(nèi)容為與mongodb中的集合task緊密相關(guān)的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資源的處理函數(shù)

資源路徑與其對應(yīng)的處理函數(shù):
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
}

具體函數(shù):

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操作

登錄系統(tǒng)并獲取jwt

post --- localhost:8890/tm2/users/login
調(diào)用:


響應(yīng):


增加數(shù)據(jù)

post --- localhost:8890/tm2/tasks/
調(diào)用:


響應(yīng):


數(shù)據(jù)庫中查看結(jié)果:


刪除數(shù)據(jù)

delete --- localhost:8890/tm2/tasks/593e72625a9c4078ae5f1a79
調(diào)用:


響應(yīng):


數(shù)據(jù)庫中查看結(jié)果(第14條數(shù)據(jù)已被刪除):


修改數(shù)據(jù)

put --- localhost:8890/tm2/tasks/593e72495a9c4078ae5f1a78
調(diào)用:


響應(yīng):


tm-p2.png

數(shù)據(jù)庫中查看結(jié)果:
原數(shù)據(jù):


新數(shù)據(jù):


獲取全部的數(shù)據(jù)

get --- localhost:8890/tm2/tasks
調(diào)用:


響應(yīng):


通過task的id獲取數(shù)據(jù)

get --- localhost:8890/tm2/tasks/t/593e6f985a9c4078ae5f1a77/
調(diào)用:


響應(yīng):


通過user的email獲取數(shù)據(jù)

get --- localhost:8890/tm2/tasks/users/007@abc.com
調(diào)用:

響應(yīng):


小結(jié)

至此,RESTful API中,user和task資源的功能已全部實(shí)現(xiàn)。實(shí)踐證明gin框架能夠很好地滿足此應(yīng)用的改造要求。
在改造的過程中,某些細(xì)節(jié)之處仍有不足,待日后慢慢完善。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容