zoukankan      html  css  js  c++  java
  • gin mongodb restful api设计: 动态的patch接口

    目录

      1. 什么是Patch?

      Patch方法可以用来更新资源的一个组成部分

      1. 什么时候使用Patch?

      当你仅需更新资源的某一项,即不完全也不幂等

      那当我们的模型在数据库中几乎每个字段都可能会遇到改变的时候,难道在patch的时候,或者专门写一个post的接口去一个一个if else操作吗,而我们又使用的是静态语言golang,有没有什么办法能够动态的让我们进行愉快的Patch呢?

      答案当然是有的,先说说如何去实现:

      1. 我们需要利用golang的map[string]interface{}结构
        • 我们需要一个动态的结构
        • 在mgo中大多使用map[string]interface{}的结构,我们直接构造出这个结构有利于我们直接进行Update({"$set": xxxx})操作
      2. 使用BindJSON函数,当然你也可以使用Gin的其他函数对map[string]interface{}进行绑定,这里我们不使用一个struct进行绑定,原因是我们无法判断客户端,或者说是浏览器会传送哪些字段来,这样做也有利于我们客户端将某一个字段置为默认值(如果用struct就只能避开默认值了)

      来,开始贴代码:

      // 这个是我们需要存到数据库中的Model
      type Article struct {
      	ID          bson.ObjectId `json:"id" bson:"_id" show:"id"`
      	Author      string        `json:"author" bson:"author" show:"author"`
      	Title       string        `json:"title" bson:"title" show:"title"`
      	Content     string        `json:"content" bson:"content" show:"content"`
      	Publish     int           `json:"publish" bson:"publish"`
      	CreatedTime int64         `json:"created_time" bson:"created_time" show:"created_time"`
      	ChangedTime int64         `json:"changed_time" bson:"changed_time" show:"changed_time"`
      	PageView    int64         `json:"page_view" bson:"page_view" show:"page_view"` // 浏览量
      	ArticleType string        `json:"article_type" bson:"article_type" show:"article_type"`
      	ArticleTags []string      `json:"article_tags" bson:"article_tags" show:"article_tags"`
      	Deleted     int           `json:"deleted" bson:"deleted"`
      }
      
      func ArticlePatch(c *gin.Context) {
      	id := c.Query("id")
      	if !bson.IsObjectIdHex(id) {
      		err_msg := "参数错误"
      		resp.SendFailJSON(c, err_msg)
      		return
      	}
      	_id := bson.ObjectIdHex(id)
      	if !CheckOwner(c) {
      		err_msg := "您没有权限"
      		resp.SendFailJSON(c, err_msg)
      		return
      	}
      	mongo := model.GetModel(model.MongoArticleCollection)
      	if mongo == nil {
      		err_msg := "网络错误"
      		resp.SendFailJSON(c, err_msg)
      		return
      	}
      	article := &model.Article{}
      	tags := common.GetAllTagValue(article, "json")
      	query := bson.M{"_id": _id, "deleted": model.ModelNotDeleted}
      	if !mongo.FindOne(article, query) {
      		err_msg := "文章不存在"
      		resp.SendFailJSON(c, err_msg)
      		return
      	}
      	patchMap := map[string]interface{}{}
      	err := c.BindJSON(&patchMap)
      	if err != nil {
      		err_msg := fmt.Sprint(err)
      		resp.SendFailJSON(c, err_msg)
      		return
      	}
      	deleteArray := []string{}
      	for k, _ := range patchMap {
      		ok, _ := common.InArray(k, tags)
      		if !ok {
      			deleteArray = append(deleteArray, k)
      		}
      	}
      	deleteCount := len(deleteArray)
      	fmt.Println("delete", deleteArray)
      	for i := 0; i < deleteCount; i++ {
      		delete(patchMap, deleteArray[i])
      	}
      	fmt.Println(patchMap)
      	if !mongo.UpdateOne(query, bson.M{"$set": patchMap}) {
      		err_msg := "更新失败"
      		resp.SendFailJSON(c, err_msg)
      		return
      	}
      	resp.SendSuccessJSON(c, "更新成功")
      }
      
      
    • 相关阅读:
      update inner join
      Centos 7安装docker
      使用Let's Encrypt搭建永久免费的HTTPS服务
      upstream timed out (10060: A connection attempt failed because the connected party did not properly respond
      MySQL死锁分析一例
      solr定时更新索引遇到的问题(SolrDataImportProperties Error loading DataImportScheduler properties java.lang.NullPointerException)
      Java中的关键字 transient
      Spring 4 使用Freemarker模板发送邮件&添加附件
      Spring 4 创建REST API
      Spring 4 异常处理
    • 原文地址:https://www.cnblogs.com/daryl-blog/p/11003091.html
    Copyright © 2011-2022 走看看