写点什么

《使用 Gin 框架构建分布式应用》阅读笔记:p77-p87

作者:codists
  • 2024-10-17
    广东
  • 本文字数:3529 字

    阅读完需:约 12 分钟

《用 Gin 框架构建分布式应用》学习第 5 天,p77-p87 总结,总计 11 页。

一、技术总结

1.Go 知识点

(1)context

2.on-premises software

p80, A container is like a separate OS, but not virtualized; it only contains the dependencies needed for that one application, which makes the container portable and deployable on-premises or on the cloud。


premises 的意思是“the land and buildings owned by someone, especially by a company or organization(归属于某人(尤指公司、组织)的土地或建筑物)”。简单来说 on-premises software 指的是运行在本地的服务(软件)。


wiki 对这个名称的定义很好,这里直接引用“On-premises software (abbreviated to on-prem, and often written as "on-premise") is installed and runs on computers on the premises of the person or organization using the software, rather than at a remote facility such as a server farm or cloud”。

3.openssl rand 命令

openssl rand -base64 12 | docker secret create mongodb_password-
复制代码


rand 命令语法:


openssl rand [-help] [-out file] [-base64] [-hex] [-engine id] [-rand files] [-writerand file] [-provider name] [-provider-path path] [-propquery propq] num[K|M|G|T]
复制代码


12 对应 num 参数。rand 详细用法参考https://docs.openssl.org/3.4/man1/openssl-rand/。对于一个命令,我们需要掌握其有哪些参数及每个参数的含义。

4.查看 docker latest tag 对应的版本号

(1)未下载镜像


打开 latest tag 对应的页面,如:https://hub.docker.com/layers/library/mongo/latest/images/sha256-e6e25844ac0e7bc174ab712bdd11bfca4128bf64d28f85d0c6835c979e4a5ff9,搜索 VERSION,然后找到版本号。


(2)已下载镜像


使用 docker inspect 命令进行查看。


# docker inspect d32 | grep -i version        "DockerVersion": "",                "GOSU_VERSION=1.17",                "JSYAML_VERSION=3.13.1",                "MONGO_VERSION=8.0.1",                "org.opencontainers.image.version": "24.04"
复制代码

5.mongo-go-driver 示例

书上代码使用的 mongo-go-driver v1.4.5,现在已经更新到了 v2.0.0,导致有些代码无法运行,建议使用最新版。这里还得再吐槽下 Go 生态圈的文档写得太糟糕了。示例:


client, _ := mongo.Connect(options.Client().ApplyURI("mongodb://localhost:27017"))ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second)defer cancel()
_ = client.Ping(ctx, readpref.Primary())
复制代码


个人认为,上面的代码 err 就不应该忽略掉。而应该是:


package main
import ( "context" "github.com/gin-gonic/gin" "github.com/rs/xid" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" "go.mongodb.org/mongo-driver/v2/mongo/readpref" "log" "net/http" "strings" "time")
type Recipe struct { ID string `json:"id"` Name string `json:"name"` Tags []string `json:"tags"` Ingredients []string `json:"ingredients"` Instructions []string `json:"instructions"` PublishAt time.Time `json:"publishAt"`}
var recipes []Recipe
func init() { // 方式1:使用内存进行初始化 // recipes = make([]Recipe, 0) // file, err := os.Open("recipes.json") // if err != nil { // log.Fatal(err) // return // } // defer file.Close() // // // 反序列化:将json转为slice // decoder := json.NewDecoder(file) // err = decoder.Decode(&recipes) // if err != nil { // log.Fatal(err) // return // }
// 方式2:使用 MongoDB 存储数据 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // 创建连接,这里的 err 针对的是 URI 错误 client, err := mongo.Connect(options.Client().ApplyURI("mongodb1://admin:admin@localhost:27017")) if err != nil { log.Fatal("MongoDB connect error: ", err) }
// 判断连接是否成功 if err := client.Ping(ctx, readpref.Primary()); err != nil { log.Fatal("MongoDB Ping error: ", err) }
log.Println("Connected to MongoDB successfully.")
}
// swagger:route POST /recipes createRecipe//// # Create a new recipe//// Responses://// 200: recipeResponse//// NewRecipeHandler 新增recipe,是按照单个新增,所以这里名称这里用的是单数func NewRecipeHandler(c *gin.Context) { var recipe Recipe if err := c.ShouldBindJSON(&recipe); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } recipe.ID = xid.New().String() recipe.PublishAt = time.Now() recipes = append(recipes, recipe) c.JSON(http.StatusOK, recipe)}
// swagger:route GET /recipes listRecipes// Returns list of recipes// ---// produces:// - application/json// responses:// '200':// description: Successful operation// ListRecipesHandler 差下recipes,因为是查询所有,所以名称这里用的是复数func ListRecipesHandler(c *gin.Context) { c.JSON(http.StatusOK, recipes)}
// UpdateRecipeHandler 更新 recipe,因为是单个,所以使用的是单数。// id 从 path 获取,其它参数从 body 获取。func UpdateRecipeHandler(c *gin.Context) { id := c.Param("id")
// 数据解码 var recipe Recipe if err := c.ShouldBindJSON(&recipe); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // 判断 id 是否存在 index := -1 for i := 0; i < len(recipes); i++ { if recipes[i].ID == id { index = i } }
// 如果 id 不存在 if index == -1 { c.JSON(http.StatusNotFound, gin.H{"error": "recipe not found"}) return } // 如果 id 存在则进行更新 recipes[index] = recipe c.JSON(http.StatusOK, recipe)}
// DeleteRecipeHandler 删除 recipe: 1.删除之前判断是否存在,存在就删除,不存在就提示不存在。func DeleteRecipeHandler(c *gin.Context) { id := c.Param("id") index := -1 for i := 0; i < len(recipes); i++ { if recipes[i].ID == id { index = i } }
if index == -1 { c.JSON(http.StatusNotFound, gin.H{"message": "recipe not found"}) return } recipes = append(recipes[:index], recipes[index+1:]...) c.JSON(http.StatusOK, gin.H{ "message": "recipe deleted", })}
// SearchRecipesHandler 查询 recipesfunc SearchRecipesHandler(c *gin.Context) { tag := c.Query("tag") listOfRecipes := make([]Recipe, 0)
for i := 0; i < len(recipes); i++ { found := false for _, t := range recipes[i].Tags { if strings.EqualFold(t, tag) { found = true } if found { listOfRecipes = append(listOfRecipes, recipes[i]) } } } c.JSON(http.StatusOK, listOfRecipes)}func main() { router := gin.Default() router.POST("/recipes", NewRecipeHandler) router.GET("/recipes", ListRecipesHandler) router.PUT("/recipes/:id", UpdateRecipeHandler) router.DELETE("/recipes/:id", DeleteRecipeHandler) router.GET("/recipes/search", SearchRecipesHandler) err := router.Run() if err != nil { return }}
复制代码

二、英语总结

1.ephemeral

p79, I opted to go with Docker duce to its popularity and simplicity in runing ephermeral environment.


(1)ephemeral: ephemera + -al。


(2)ephemera: epi-("on") + hemera("day"), lasting one day , short-lived"。

三、其它

从目前的阅读体验来看,作者默认读者充分掌握 Golang,丝毫不会展开介绍。

四、参考资料

1. 编程

(1) Mohamed Labouardy,《Building Distributed Applications in Gin》:https://book.douban.com/subject/35610349

2. 英语

(1) Etymology Dictionary:https://www.etymonline.com

(2) Cambridge Dictionary:https://dictionary.cambridge.org


欢迎搜索及关注:编程人(a_codists)

用户头像

codists

关注

公众号:编程人 2021-01-14 加入

Life is short, You need Python

评论

发布
暂无评论
《使用Gin框架构建分布式应用》阅读笔记:p77-p87_Go_codists_InfoQ写作社区