GO restful api 用法
前言:
最近公司开发写一个 Prometheus 的 webhook 系统,但是每次都需要在页面上点击操作,所以领导让我编写一个第三方工具,从而实现能够快速创建对应用户、信息、规则等
虽然 webhook 系统是由 java 编写,但是接口采用的是 restful api 所以我们通过 go 编写也能够直接调用
完整项目地址:https://github.com/As9530272755/Tool-set/tree/master/cwms-ctl
1 什么是 restful Api
当我们需要使用对应的 restful api 那么就需要提前了解他是什么
REST API 也称为 RESTful API,是遵循 REST 架构规范的应用编程接口(API 或 Web API),支持与 RESTful Web 服务进行交互。REST 是表述性状态传递的英文缩写,由计算机科学家 Roy Fielding 创建。
1.1 什么是 API
API 由一组定义和协议组合而成,可用于构建和集成应用软件。有时我们可以把它们当做信息提供者和信息用户之间的合同——建立消费者(呼叫)所需的内容和制作者(响应)要求的内容。例如,天气服务的 API 可指定用户提供邮编,制作者回复的答案由两部分组成,第一部分是最高温度,第二部分是最低温度。
换言之,如果您想与计算机或系统交互以检索信息或执行某项功能,API 可帮助您将您需要的信息传达给该系统,使其能够理解并满足您的请求。
您可以把 API 看做是用户或客户端与他们想要的资源或 Web 服务之间的传递者。它也是企业在共享资源和信息的同时保障安全、控制和身份验证的一种方式,即确定哪些人可以访问什么内容。
API 的另一个优势是您无需了解缓存的具体信息,即如何检索资源或资源来自哪里。
详细请查看:详细了解 API
1.2 如何理解 REST 的含义?
REST 是一组架构规范,并非协议或标准。API 开发人员可以采用各种方式实施 REST。
当客户端通过 RESTful API 提出请求时,它会将资源状态表述传递给请求者或终端。该信息或表述通过 HTTP 以下列某种格式传输:JSON(Javascript 对象表示法)、HTML、XLT、Python、PHP 或纯文本。JSON 是最常用的编程语言,尽管它的名字英文原意为“JavaScript 对象表示法”,但它适用于各种语言,并且人和机器都能读。
还有一些需要注意的地方:头和参数在 RESTful API HTTP 请求的 HTTP 方法中也很重要,因为其中包含了请求的元数据、授权、统一资源标识符(URI)、缓存、cookie 等重要标识信息。有请求头和响应头,每个头都有自己的 HTTP 连接信息和状态码。
1.3 如何实现 RESTful API?
API 要被视为 RESTful API,必须遵循以下标准:
- 客户端-服务器架构由客户端、服务器和资源组成,并且通过 HTTP 管理请求。
- 无状态客户端-服务器通信,即 get 请求间隔期间,不会存储任何客户端信息,并且每个请求都是独立的,互不关联。
- 可缓存性数据:可简化客户端-服务器交互。
- 组件间的统一接口:使信息以标准形式传输。这要求:
- 所请求的资源可识别并与发送给客户端的表述分离开。
- 客户端可通过接收的表述操作资源,因为表述包含操作所需的充足信息。
- 返回给客户端的自描述消息包含充足的信息,能够指明客户端应该如何处理所收到的信息。
- 超文本/超媒体可用,是指在访问资源后,客户端应能够使用超链接查找其当前可采取的所有其他操作。
- 组织各种类型服务器(负责安全性、负载平衡等的服务器)的分层系统会参与将请求的信息检索到对客户端不可见的层次结构中。
- 按需编码(可选):能够根据请求将可执行代码从服务器发送到客户端,从而扩展客户端功能。
虽然 REST API 需要遵循这些标准,但是仍比遵循规定的协议更容易,如 SOAP(简单对象访问协议),该协议具有 XML 消息传递、内置安全性和事务合规性等具体要求,因此速度较慢、结构繁重。
相比之下,REST 则是一组可按需实施的准则,使 REST API 速度更快、更轻,可扩展性更高,非常适合物联网(IoT)和移动应用开发。
2 功能编写
这里我只演示如何 login 和 创建用户 的功能,其他功能直接在 GitHub 上查看详细代码,而且每个功能其实都差不多,只要会了一个其他都一样
这里通过 webhook 系统的登录页面可以看到他的 rul 是 http://10.0.0.134:8011/user/login 并且请求方法是 POST
点击 Payload 查看对应的字段是 username 和 password 那么等会我们就要编写一个 client 程序来实现请求这个 API 从而实现登录
2.1 编写 login
package controller
import (
"encoding/json"
"io/ioutil"
"net/http"
"net/url"
)
func Login() string {
var result map[string]string
// 我通过读取配置文件获取,如果不读取直接写 url 地址也是可以的如 http://10.0.0.134:8011/user/login
api := Config() + `/user/login`
// 获取 token
response, err := http.PostForm(api, url.Values{
// 只需将 User、Password 修改为我们对应的用户密码即可
"username": {User},
"password": {Passwrod},
})
if err != nil {
panic(err)
}
defer response.Body.Close()
// 请求体,用来获取 token
body, err := ioutil.ReadAll(response.Body)
if err == nil {
json.Unmarshal([]byte(string(body)), &result)
}
// 获取 token
token := result["token"]
// 这里我将获取到的 token 返回等会用于校验
return token
}
2.2 编写创建用户
1 查看创建用户 api,可以看到这个就是他的一个结构体
2 当我们拿到了创建用户的结构体之后就需要编写一个 models 模块,因为我们需要在请求的时候将该 user 结构体发送至 server
package model
import "time"
// 人员信息
type user struct {
Comment string `json:"comment"`
Email string `json:"email"`
Name string `json:"name"`
Phone string `json:"phone"`
Role string `json:"role"`
Wechat_id string `json:"wechat_id"`
}
func NewUser() *user {
return &user{
Name: "null",
Email: "null",
Phone: "null",
Wechat_id: "null",
Role: "null",
Comment: "null",
}
}
3 编写对应主程序,该代码中我使用了 cobra
来作为命令行脚手架工具,这里不再赘述使用方法参考我往期的文章:Cobra 初体验
package cmd
import (
"cwms-ctl/controller"
"cwms-ctl/model"
"fmt"
"github.com/spf13/cobra"
)
// adduserCmd represents the adduser command
var adduserCmd = &cobra.Command{
Use: `adduser 用户名 邮件 手机 企微 角色 备注
命令说明:
默认必须使用 6 个参数分别为顺序分别是:用户名,邮件,手机,企微,角色,备注说明;但是可以通过子参数对单个字段进行单独创建
如某字段指定 null 如下示例:
例子: cwms-ctl adduser 用户名 邮件 手机 企微 null null
解释: 对角色和备注字段定义为 null`,
Short: `该子命令用于创建用户`,
Long: `该子命令用于创建用户`,
Run: func(cmd *cobra.Command, args []string) {
DefaultCreateUser(args)
}
}
func init() {
RootCmd.AddCommand(adduserCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// adduserCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
}
func UserApi() (api string) {
// 我通过读取配置文件获取,如果不读取直接写 url 地址也是可以的如 http://10.0.0.134:8011/staff/update
web := controller.Config()
paht := `/staff/update`
return web + paht
}
// 通过命令传入的参数获取对应的用户信息
func DefaultCreateUser(args []string) {
payload := model.NewUser()
payload.Name = args[0]
payload.Email = args[1]
payload.Phone = args[2]
payload.Wechat_id = args[3]
payload.Role = args[4]
payload.Comment = args[5]
// 调用 put 方法实现创建,并传入实例化的 payload 和对应的 api
controller.Put(payload, UserApi())
}
以上就是创建用户的所需要的代码,那么我们还需将获取到的用户信息发送至客户端,所以编写一个 put 方法从而实现创建,可以在下图看到是一个 PUT 方法
2.3 编写调用 API 实现创建 user 方法
package controller
import (
"encoding/json"
"log"
"net/http"
"strings"
)
// 接收 payload 和 api
func Put(payload interface{}, api string) {
// 转为 byte 格式
jsonPayload, err := json.Marshal(payload)
if err != nil {
log.Panic(err)
}
// 转为 reader
body := strings.NewReader(string(jsonPayload))
// 提交数据
req, _ := http.NewRequest("PUT", api, body)
req.Header.Add("Content-Type", "application/json")
// token 校验,这里使用过 login() 方法返回得到
req.Header.Add("token", Login())
response, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer response.Body.Close()
}
3 验证
以上我们就写完了所有的程序,那么我们验证观察,可以看到在 adduser 子命令以及生成
1 查看 adduser 子命令帮助
root@ubuntu:~/go/src/cwms-ctl# go run main.go adduser -h
该子命令用于创建用户
Usage:
cwms-ctl adduser 用户名 邮件 手机 企微 角色 备注
命令说明:
默认必须使用 6 个参数分别为顺序分别是:用户名,邮件,手机,企微,角色,备注说明;但是可以通过子参数对单个字段进行单独创建
如某字段指定 null 如下示例:
例子: cwms-ctl adduser 用户名 邮件 手机 企微 null null
解释: 对角色和备注字段定义为 null [flags]
2 创建用户
root@ubuntu:~/go/src/cwms-ctl# go run main.go adduser testLOL as933@qq.com 177xxx zgy admin 测试用户
3 浏览器验证
总结:
以上就是使用 restful API 的案例,这样直接通过命令创建然后在写一个自动化脚本既可以实现多用户等功能的使用