0
点赞
收藏
分享

微信扫一扫

ch2-设置API--使用go-gin创建分布式应用

Villagers 2022-02-15 阅读 45

系列文章目录

第一章 gin初步认识
第二章 设置API


目录


在这里插入图片描述


注:

  1. 系列文章是对应上述英文原版书的学习笔记
  2. 相关自己的练习代码包含注释,放在在本人的gitee,欢迎star
  3. 所有内容允许转载,如果侵犯书籍的著作权益,请联系删除
  4. 笔记持续更新中

设置API

前言

本章将介绍如何构建RESTful API
介绍HTTP的其他方法和路由(router)的方法。
还有如何编写OpenAPI和生成API文档。

gin框架的微服务应用架构

在这里插入图片描述

简单的说就是,微服务通过暴露RESTful API来管理http协议下的方法(recipes)

定义数据模型

type Recipe struct {
   Name         string    `json:"name"` // 使用注解指定字段
   Tags         []string  `json:"tags"`
   Ingredients  []string  `json:"ingredients"`
   Instructions []string  `json:"instructions"`
   PublishedAt  time.Time `json:"PublishedAt"`
}

在数据模型后面加上注解,有助于GoJSON在字段名

http结点方法

在这里插入图片描述

实现HTTP路由

1. 定义全局变量,用来存储数据

使用数据库后,就可以直接使用数据库返回的数据

var recipes []Recipe
func init() {
    recipes = make([]recipes, 0)
}

2. 编写POST响应处理函数

func NewRecipeHandler(c *gin.Context) {
   var recipe Recipe
    // 从POST请求的正文中获取并绑定到数据实体
    // c.ShouldBindJSON(&recipe)
   if err := c.ShouldBindJSON(&recipe); err != nil {
      c.JSON(http.StatusBadRequest, gin.H{
         "error": err.Error()})
      return
   }
   // 生成独一无二的ID代码
   recipe.ID = xid.New().String()
   recipe.PublishedAt = time.Now()
   recipes = append(recipes, recipe)
   // 把数据模型实体recipe返回为json模式
   c.JSON(http.Status(OK, recipe)
}

3. 编写GET响应函数

func ListRecipesHandler(c *gin.Context) {
   c.JSON(http.StatusOK, recipes)
}

4. 从json文件获取数据,初始化实体

func init() {
   // 使用文本文件json模拟数据库用于初始化数据模型
   recipes = make([]Recipe, 0)
   // 一般go会在项目的root路径下寻找文件
   file, _ := ioutil.ReadFile("recipes.json")
   _ = json.Unmarshal([]byte(file), &recipes)
}

5. 编写PUT响应函数,更新指定数据

// URL传参ID,对指定的实体数据更新
func UpdateRecipeHandler(c *gin.Context) {
   id := c.Param("id")
   var recipe Recipe
   // 1. 用body初始化实体
   if err := c.ShouldBindJSON(&recipe); err != nil {
      c.JSON(http.StatusBadRequest, gin.H{
         "error": err.Error()})
      return
   }
   // 在本地数据里面定位URL指定ID的recipe
   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{
         "error": "Recipe not found"})
      return
   }
   // 把找到的recipe更新到本地数据
   recipes[index] = recipe
   c.JSON(http.StatusOK, recipe)
}

6. 编写DELETE响应函数,查找并删除指定实体

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{
         "error": "Recipe not found"})
      return
   }
   // 数组拼接的方法删除下标为index的元素
   recipes = append(recipes[:index], recipes[index+1:]...)
   c.JSON(http.StatusOK, gin.H{
      "message": "Recipe has been deleted"})
}

7. 编写GET/recipes/search?tag=?响应函数

// URL传参ID,对指定的实体数据更新
func UpdateRecipeHandler(c *gin.Context) {
   id := c.Param("id")
   var recipe Recipe
   // 1. 用body初始化实体
   if err := c.ShouldBindJSON(&recipe); err != nil {
      c.JSON(http.StatusBadRequest, gin.H{
         "error": err.Error()})
      return
   }
   // 在本地数据里面定位URL指定ID的recipe
   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{
         "error": "Recipe not found"})
      return
   }
   // 把找到的recipe更新到本地数据
   recipes[index] = recipe
   c.JSON(http.StatusOK, recipe)
}

编写OpenAPI说明(OAS)

OAS作为API说明或者API定义语言,当你描述一个API的时候,应该包含如下的信息:

  • API的基本信息
  • 有效的路径和操作(HTTP方法)
  • 每个操作对应的期待的输入(查询,路径参数,请求体等)和响应(HTTP状态码,响应体等)

使用Go Swagger生成API说明

  1. package main上一行,编写API的说明信息
// Recipes API
//
// This is a sample recipes API.
//
// Schemes: http
// host: localhost:8080
// BasePath: /
// Version: 1.0.0
// Contact: Mohamed Labouardy <mohamed@labourdy.com> https://labourardy.com
//
// Consumes:
// - application/json
//
// Produces:
// - application/json
// swagger:meta

在项目根目录执行

这件生成json类型的说明文档,如果后缀是yml或者yaml会生成YAML文件

执行

将依据刚才生成的文档,渲染打开一个本地网站用于可视化展示文档

  1. 在Handler函数上编写特定的API的文档
// swagger:operation GET /recipes recipes listRecipes
// Returns list of recipes
// ---
// produces:
// - application/json
// responses:
// '200':
// description: Successful operation
func ListRecipesHandler(c *gin.Context) {
   c.JSON(http.StatusOK, recipes)
}
// swagger:operation PUT /recipes/{id} recipes updateRecipe
// Update an existing recipe
// ---
// parameters:
// - name: id
// in: path
// description: ID of the recipe
// required: true
// type: string
// produces:
// - application/json
// responses:
// '200':
// description: Successful operation
func UpdateRecipeHandler(c *gin.Context)
举报

相关推荐

0 条评论