一、介绍
本文解释了如何在Go with Vultr Managed Databases for MySQL 中构建安全的REST API。通过遵循本指南,您将为 MySQL 创建一个 Vultr 托管数据库,使用 TLS 安全地连接到它,使用 Go MySQL 客户端执行 CRUD(创建、读取、更新、删除)操作,并使用 Gin Web 框架构建 REST API。
1.1、MySQL 客户端库
最流行的 MySQL 库之一是 C API,它为命令行客户端、MySQL 连接器和第三方 API 提供对 MySQL 的低级访问。MySQL为其他流行的编程语言提供连接器(库或驱动程序)。其中包括JDBC(用于Java应用程序),.NET,Python,Node.js,Ruby,PHP 和 Perl 等。这些连接器/库/驱动程序要么使用 (使用编程语言提供的 C 绑定) 或通过实现本机驱动程序构建。每种方法都有优点和缺点。libmysqlclient
libmysqlclient
本机驱动程序完全在主机语言或环境中实现 MySQL 网络协议。它们速度快,可以提供高级功能,并且最终用户更容易构建和部署,因为构建本机驱动程序组件不需要 MySQL 客户端库的副本。
使用提供与 MySQL 的完全兼容性,但它们的功能集仅限于通过 公开的接口,并且性能可能会降低(与本机驱动程序相比),因为数据是在本机语言和 MySQL API 组件之间复制的。libmysqlclient
libmysqlclient
1.2、MySQL Go 客户端
Go MySQL 驱动程序是 Go 包的 MySQL 驱动程序。它是一个原生的 Go 实现,支持丰富的功能集,其中包括:database/sql
- 连接池。
- 支持大于 16 MB 的查询。
- 支持 sql。原始字节。
- 通过 TCP/IPv4、TCP/IPv6、Unix 域套接字或自定义协议进行连接。
1.3、GIN 网络框架
Gin
是一个使用该库的 HTTP 高性能 Web 框架。它的一些主要功能包括:httprouter
- Gin 为 JSON、XML 和 HTML 渲染提供了一个易于使用的 API,它提供了实用工具来帮助解析和验证 HTTP 请求中的 JSON 有效负载,并处理 HTTP 响应的 JSON。
- 您可以使用中间件修改传入的 HTTP 请求,并实现授权、身份验证、日志记录和压缩等功能。
- 避免服务器崩溃,因为 Gin 可以在 HTTP 请求期间捕获错误并正常恢复。
- 您可以有效地管理应用程序的 HTTP 路由。这对于处理不同 API 版本等用例非常有用。这些 HTTP 路由组提供无限制的嵌套,而不会降低性能。
二、准备工作先
若要按照本文中的说明进行操作,请执行以下操作:
- 安装最新版本的 Go 编程语言(版本 1.18 或更高版本)
- 安装 curl,一个流行的命令行 HTTP 客户端。
三、创建 Vultr MySQL 托管数据库
登录您的 Vultr 帐户,导航到添加托管数据库。
选择 MySQL 数据库引擎。
您可以从“服务器类型”中的多个选项中进行选择。这包括云计算、云计算高性能(AMD 或英特尔)和优化云计算 – 通用、存储或内存优化。
还应选择零个或多个副本节点以及群集位置。副本节点与主节点的服务器类型和计划相同。
本文使用不带副本节点的云计算服务器类型。
为数据库集群添加标签后,单击立即部署以创建集群。群集需要几分钟时间才能可用,并且“状态”应更改为“正在运行”。
Vultr MySQL 托管数据库已准备就绪,您可以使用 Go 程序连接到它。
四、初始化项目
创建一个目录并切换到该目录:
mkdir mysql-go-gin-api
cd mysql-go-gin-api
创建一个新的 Go 模块:
go mod init mysql-go-gin-api
这将创建一个新文件
go.mod
创建一个新文件:main.go
touch main.go
五、导入库
要导入所需的 Go 模块,请将以下内容添加到文件中:main.go
package main
import (
"crypto/tls"
"crypto/x509"
"database/sql"
"fmt"
"io/ioutil"
"log"
"os"
"github.com/gin-gonic/gin"
"github.com/go-sql-driver/mysql"
_ "github.com/go-sql-driver/mysql"
)
将导入以下包:
database/sql
– 此包包括用于连接和使用 SQL 数据库的类型和函数。github.com/go-sql-driver/mysql
– 虽然为 SQL 数据库提供了通用接口,但您需要要使用的特定数据库的驱动程序。在这种情况下,您使用的是 MySQL 数据库及其相应的驱动程序。驱动程序以匿名方式加载(别名在其包限定符中使用)并注册。database/sql
_
github.com/gin-gonic/gin
– 提供Gin Web框架支持
六、添加全局变量和常量
将以下代码添加到文件中:main.go
const urlTemplate = "%s:%s@tcp(%s:%s)/%s?tls=custom"
const createTable = `CREATE TABLE users (
Userid int NOT NULL AUTO_INCREMENT,
Email varchar(255) NOT NULL,
Name varchar(255) NOT NULL,
PRIMARY KEY (userid)
);
`
const dropTable = `DROP TABLE users;`
var username string
var password string
var host string
var port string
var dbname string
var certificateLocation string
var db *sql.DB
- 常量和分别是用于创建和删除 MySQL 表的查询。
createTable
dropTable
- 变量在函数中初始化。
init
七、添加函数init
将以下代码添加到文件中:main.go
func init() {
username = os.Getenv("MYSQL_USERNAME")
if username == "" {
log.Fatal("missing environment variable MYSQL_USERNAME")
}
password = os.Getenv("MYSQL_PASSWORD")
if password == "" {
log.Fatal("missing environment variable MYSQL_PASSWORD")
}
host = os.Getenv("MYSQL_HOST")
if host == "" {
log.Fatal("missing environment variable MYSQL_HOST")
}
port = os.Getenv("MYSQL_PORT")
if port == "" {
log.Fatal("missing environment variable MYSQL_PORT")
}
dbname = os.Getenv("MYSQL_DBNAME")
if dbname == "" {
log.Fatal("missing environment variable MYSQL_DBNAME")
}
certificateLocation = os.Getenv("MYSQL_TLS_CERT_LOCATION")
if certificateLocation == "" {
log.Fatal("missing environment variable MYSQL_TLS_CERT_LOCATION")
}
url := fmt.Sprintf(urlTemplate, username, password, host, port, dbname)
rootCertPool := x509.NewCertPool()
pem, err := ioutil.ReadFile(certificateLocation)
if err != nil {
log.Fatal(err)
}
if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
log.Fatal("failed to append pem")
}
mysql.RegisterTLSConfig("custom", &tls.Config{
RootCAs: rootCertPool,
})
db, err = sql.Open("mysql", url)
if err != nil {
log.Fatal("invalid mysql url", err)
}
err = db.Ping()
if err != nil {
log.Fatal("failed to connect with mysql", err)
}
fmt.Println("successfully connected to mysql")
}
该函数处理两件重要的事情:init
- 第一个是通过环境变量检索连接信息。这包括 Vultr MySQL 托管数据库主机、端口、用户名、密码、数据库名称、证书位置(分别来自、、、、和)。
MYSQL_HOST
MYSQL_PORT
MYSQL_USERNAME
MYSQL_PASSWORD
MYSQL_DBNAME
MYSQL_TLS_CERT_LOCATION
- 其次,还建立了数据库连接(使用)。它创建一个指向对象的指针,该对象表示与基础数据库的零个或多个连接的池。
sql.Open
sql.DB
八、添加函数main
将函数添加到文件:main
main.go
func main() {
}
该函数留空,因为我们的目标(在下一节中)是确保您能够连接到 MySQL 数据库。本文稍后将在添加应用程序逻辑的其余部分时更新该函数。main
main
九、连接到 Vultr MySQL 托管数据库
要使用Go程序与Vultr MySQL托管数据库建立连接,您需要获取连接详细信息。在继续之前,您需要执行以下操作:
- 获取要连接到它的数据库的连接详细信息。
- 下载 TLS 证书。
获取连接详细信息:
- 单击管理图标以打开概述选项卡。
- 从“连接详细信息”部分中,复制以下属性:、、 和
username
password
host
host
port
database
要下载签名证书,请单击下载签名证书并将其保存到本地计算机上的某个位置。
获取程序的 Go 模块依赖项:
go mod tidy
您可能会得到以下输出:
go: finding module for package github.com/go-sql-driver/mysql
go: found github.com/go-sql-driver/mysql in github.com/go-sql-driver/mysql v1.7.0
要运行该程序:
export MYSQL_USERNAME=<enter the Vultr MySQL Managed Database username e.g. vultradmin>
export MYSQL_PASSWORD=<enter the Vultr MySQL Managed Database password>
export MYSQL_HOST=<enter the Vultr MySQL Managed Database hostname>
export MYSQL_PORT=<enter the Vultr MySQL Managed Database port e.g. 16751>
export MYSQL_DBNAME=<enter the Vultr MySQL Managed Database database name e.g. defaultdb>
export MYSQL_TLS_CERT_LOCATION=<enter the certificate location for Vultr MySQL Managed Database>
go run main.go
如果已建立连接,则应看到以下输出:
successfully connected to mysql
现在,您可以添加应用程序逻辑的其余部分。
十、在 MySQL 中向表中添加数据users
HTTP 处理程序用于向表中添加行。createUser
创建一个新文件:handler.go
touch handler.go
添加导入
将导入添加到文件:handler.go
package main
import (
"database/sql"
"errors"
"fmt"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
)
添加 HTTP 处理程序
若要将 HTTP 处理程序添加到处理请求,请将以下代码添加到文件中:handler.go
const insertQuery = `INSERT into users (Email, Name) VALUES (?, ?);`
func createUser(c *gin.Context) {
fmt.Println("creating user")
var req CreateUserRequest
err := c.ShouldBind(&req)
if err != nil {
c.AbortWithError(http.StatusBadRequest, err)
return
}
r, err := db.Exec(insertQuery, req.Email, req.Name)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
id, err := r.LastInsertId()
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
fmt.Println("created user with id", id)
c.Status(http.StatusCreated)
c.Header("Location", "/"+strconv.Itoa(int(id)))
fmt.Println("user created successfully")
}
添加创建用户请求消息
创建一个新文件:model.go
touch model.go
将以下代码添加到文件中:model.go
package main
type CreateUserRequest struct {
Email string `json: "email"`
Name string `json: "name"`
}
createUser
函数接受对象。gin.Context
CreateUserRequest
表示包含有关要创建的用户的信息的有效负载( 和 )。Email
Name
ShouldBind
将请求正文解析为 JSON(因为您将使用标头)。它将 JSON 有效负载解码为指定为指针。application/json
Content-Type
CreateUserRequest
struct
Exec
用于使用从 HTTP 有效负载正文检索的用户名和电子邮件对数据库执行插入查询 ( 查询。INSERT into users (Email, Name) VALUES (?, ?);
- 如果行添加成功,您将获得自动生成的行 ID(主键),并将其作为标头返回 HTTP 响应(以及 201 Created HTTP 响应)。
Location
十一、查询用户的方式Userid
HTTP 处理程序用于使用其 .getUserWithID
id
将以下代码添加到文件中:handler.go
const getUserWithIdQuery = `SELECT * FROM users where Userid=?;`
func getUserWithID(c *gin.Context) {
userid := c.Param("id")
fmt.Println("getting user with id", userid)
res := db.QueryRow(getUserWithIdQuery, userid)
if res.Err() != nil {
c.AbortWithError(http.StatusInternalServerError, res.Err())
return
}
var id int
var email string
var name string
err := res.Scan(&id, &email, &name)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
fmt.Println("user with id", userid, "does not exist")
c.AbortWithError(http.StatusNotFound, err)
return
}
c.AbortWithError(http.StatusInternalServerError, err)
return
}
user := GetUserResponse{UserID: id, Email: email, Name: name}
c.JSON(http.StatusOK, user)
fmt.Println("successfully retrieved details for user with id", userid)
}
将以下代码添加到文件中:model.go
type GetUserResponse struct {
UserID int `json: "userid"`
Email string `json: "email"`
Name string `json: "name"`
}
getUserWithID
接受对象。gin.Context
- 您可以使用命名参数提取用户 ID。它作为 HTTP 请求 URL 中的路径参数传入,并使用函数检索。
Param
QueryRow
用于对具有先前检索的用户 ID 的数据库执行查询。SELECT * FROM users where Userid=?;
- 完成后,使用 Scan 从匹配的查询结果(行)中复制列。
- 如果返回错误,请使用 HTTP 404 (StatusNotFound) 进行响应 – 这意味着您尝试搜索的用户 ID 在表中尚不存在。
sql.ErrNoRows
- 如果是有效的响应(用户信息),则以结构的形式表示该响应,其中包含用户 ID、电子邮件和所查询用户的名称。JSON 函数用于方便地以 HTTP 响应的形式返回此 Go,而无需执行显式 JSON 封送处理或解码。
GetUserResponse
struct
十二、获取所有用户
HTTP 处理程序用于检索表中的所有行。getAllUsers
users
将以下代码添加到文件中:handler.go
const getAllUsersQuery = `SELECT * FROM users;`
func getAllUsers(c *gin.Context) {
fmt.Println("getting all users")
res, err := db.Query(getAllUsersQuery)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
var users []GetUserResponse
for res.Next() {
var id int
var email string
var name string
err := res.Scan(&id, &email, &name)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
user := GetUserResponse{UserID: id, Email: email, Name: name}
users = append(users, user)
}
if len(users) == 0 {
fmt.Println("no users found")
c.AbortWithStatus(http.StatusNotFound)
return
}
c.JSON(http.StatusOK, users)
fmt.Println("successfully retrieved details for all users")
}
getAllUsers
函数接受对象。gin.Context
Query
用于对数据库执行查询。SELECT * FROM users;
- 对于从查询返回的每一行,用于从匹配的查询结果中复制列。
Scan
- 由此,创建一个对象并将其添加到切片中。
GetUserResponse
- 如果切片没有元素,则可以确定表中当前没有用户,因此返回 HTTP 404 (NotFound) 作为响应。在查询成功的情况下,JSON 函数用于方便地以 HTTP 响应的形式返回结构片,而无需执行显式 JSON 封送处理或解码。
GetUserResponse
十三、更新用户Userid
HTTP 处理程序用于更新给定其 .updateUser
id
将以下代码添加到文件中:handler.go
const updateQuery = `UPDATE users SET Name = ? WHERE Userid = ?;`
func updateUser(c *gin.Context) {
var req UpdateRequest
err := c.ShouldBind(&req)
if err == nil {
fmt.Println("got user update request", req)
}
fmt.Println("updating user with id", req.UserID)
res, err := db.Exec(updateQuery, req.NewName, req.UserID)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
numRows, err := res.RowsAffected()
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
if numRows == 0 {
fmt.Println("unable to find user with id", req.UserID)
c.AbortWithStatus(http.StatusNotFound)
return
}
fmt.Println("updated user with id", req.UserID)
c.Status(http.StatusOK)
}
将以下代码添加到文件中:model.go
type UpdateRequest struct {
UserID string `json: "userid"`
NewName string `json: "name"`
}
getAllUsers
函数接受对象。gin.Context
UpdateRequest
表示包含有关要更新的用户的信息的有效负载( 和 )。UserID
NewName
ShouldBind
将请求正文解析为 JSON(因为您将使用标头)。它将 JSON 有效负载解码为指定为指针。application/json
Content-Type
UpdateRequest
struct
Exec
用于执行更新查询 ( 使用从 HTTP 有效负载正文检索的新用户名和用户 ID 对数据库执行查询。UPDATE users SET Name = ? WHERE Userid = ?;
- 要验证更新操作是否成功,请对对象执行以确认一行已受到影响。
RowsAffected
sql.Result
- 如果不是,则可以确定表中不存在您尝试更新的用户 ID,因此返回 HTTP 404 (NotFound) 作为响应。否则,将返回 HTTP 200(正常)。
十四、删除用户依据Userid
HTTP 处理程序用于更新给定其 .deleteUserWithID
id
将以下代码添加到文件中:handler.go
const deleteWithIdQuery = `DELETE FROM users WHERE Userid = ?;`
func deleteUserWithID(c *gin.Context) {
userid := c.Param("id")
fmt.Println("deleting user with id", userid)
r, err := db.Exec(deleteWithIdQuery, userid)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
numRows, err := r.RowsAffected()
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
if numRows == 0 {
fmt.Println("unable to find user with id", userid)
c.AbortWithStatus(http.StatusNotFound)
return
}
fmt.Println("successfully deleted user with id", userid)
c.Status(http.StatusOK)
}
deleteUserWithID
函数接受对象。gin.Context
- 使用命名参数提取用户 ID。它作为 HTTP 请求 URL 中的路径参数传入,并使用函数检索。
Param
Exec
用于执行删除查询 ( 对具有先前检索的用户 ID 的数据库的查询。DELETE FROM users WHERE Userid = ?;
- 要验证删除操作是否成功,请对对象执行以确认某一行已受到影响。
RowsAffected
sql.Result
- 如果不是,则可以确定表中不存在您尝试删除的用户 ID,因此返回 HTTP 404 (NotFound) 作为响应。否则,将返回 HTTP 200(正常)。
十五、初始化 MySQL 数据库中的表
该函数删除表并重新创建它。dropAndCreateTable
users
将以下代码添加到文件中:main.go
func dropAndCreateTable() {
_, err := db.Exec(dropTable)
if err != nil {
fmt.Println("could not drop table -", err)
} else {
fmt.Println("table dropped")
}
_, err = db.Exec(createTable)
if err != nil {
log.Fatal("could not create table", err)
}
fmt.Println("table created")
}
更新函数以调用函数(添加到函数末尾):init
init
dropAndCreateTable()
Exec
用于对数据库执行查询,后跟查询。DROP TABLE
CREATE TABLE
十六、添加 HTTP 路由并启动 HTTP 服务器
您之前添加的 HTTP 处理程序(在 handler.go 文件中)需要配置为路由。
将以下代码添加到文件中的函数(之前为空):main
main.go
r := gin.New()
gin.SetMode(gin.ReleaseMode)
r.POST("/", createUser)
r.GET("/:id", getUserWithID)
r.GET("/", getAllUsers)
r.PUT("/", updateUser)
r.DELETE("/:id", deleteUserWithID)
r.Run("localhost:8080")
另外,将杜松子酒包添加到 – 部分。imports
" github.com/gin-gonic/gin"
现在,您已准备好运行程序并测试 API。
十七、运行并测试应用程序
获取程序的 Go 模块依赖项:
go mod tidy
您应该看到类似于以下内容的输出:
go: finding module for package github.com/gin-gonic/gin
go: found github.com/gin-gonic/gin in github.com/gin-gonic/gin v1.8.1
要运行该程序:
export MYSQL_USERNAME=<enter the Vultr MySQL Managed Database username e.g. vultradmin>
export MYSQL_PASSWORD=<enter the Vultr MySQL Managed Database password>
export MYSQL_HOST=<enter the Vultr MySQL Managed Database hostname>
export MYSQL_PORT=<enter the Vultr MySQL Managed Database port e.g. 16751>
export MYSQL_DBNAME=<enter the Vultr MySQL Managed Database database name e.g. defaultdb>
export MYSQL_TLS_CERT_LOCATION=<enter the certificate location for Vultr MySQL Managed Database>
go run *.go
您应该看到类似于以下内容的输出日志:
successfully connected to mysql
could not drop table - Error 1051: Unknown table' defaultdb.users'
table created
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
注意:不用担心日志消息。仅当您首次运行程序时,才会发生这种情况。如果再次重新运行该程序,将不会发生这种情况,因为该表已存在于 Vultr MySQL 托管数据库实例中。could not drop table - Error 1051: Unknown table' defaultdb.users
users
现在,您可以使用 HTTP 端点来测试 API 的创建、读取、更新和删除功能。
17.1、创建几个用户
要创建用户(使用用户名和电子邮件地址),请在终端中运行以下命令:user1
user1@foo.com
curl -i -XPOST -H "Content-Type: application/json" -d '{"email": "user1@foo.com", "name": "user1"}' localhost:8080/
您应该返回类似于以下内容的 HTTP 响应:
HTTP/1.1 201 Created
Location: /1
Date: Mon, 01 Jan 2020 00:00:00 GMT
Content-Length: 0
要创建用户(使用用户名和电子邮件地址),请在终端中运行以下命令:user2
user2@foo.com
curl -i -XPOST -H "Content-Type: application/json" -d '{"email": "user2@foo.com", "name": "user2"}' localhost:8080/
您应该返回类似于以下内容的 HTTP 响应:
HTTP/1.1 201 Created
Location: /2
Date: Mon, 01 Jan 2020 00:00:00 GMT
Content-Length: 0
请注意,HTTP 标头包含 MySQL 自动生成的用户 ID。Location
17.2、按 ID 检索用户
要获取具有 ID 的用户的详细信息,请在终端中运行以下命令:1
curl -i localhost:8080/1
您应该返回类似于以下内容的 HTTP 响应:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Mon, 01 Jan 2020 00:00:00 GMT
Content-Length: 51
{"userid":1,"email":"user1@foo.com","name":"user1"}
要获取具有 ID 的用户的详细信息,请在终端中运行以下命令:2
curl -i localhost:8080/2
您应该返回类似于以下内容的 HTTP 响应:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Mon, 01 Jan 2020 00:00:00 GMT
Content-Length: 51
{"userid":2, "email": "user2@foo.com", "name": "user2"}
您可以获取 JSON 形式的用户信息有效负载以及 HTTP 响应元数据。
要获取具有 ID 的用户的详细信息,请在终端中运行以下命令:42
curl -i localhost:8080/42
您应该返回类似于以下内容的 HTTP 响应:
HTTP/1.1 404 Not Found
Date: Mon, 01 Jan 2020 00:00:00 GMT
Content-Length: 0
正如预期的那样,您得到了一个 HTTP 404,因为数据库中尚不存在具有 ID 的用户。42
17.3、抓取所有用户
要获取表中的所有行,请在终端中运行以下命令:users
curl -i localhost:8080/
您应该返回类似于以下内容的 HTTP 响应:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Mon, 01 Jan 2020 00:00:00 GMT
Content-Length: 105
[{"userid ":1, "email": "user1@foo.com", "name": "user1"},{"userid":2, "email": "user2@foo.com", "name": "user2"}]
您可以获取 JSON 形式的用户数组以及 HTTP 响应元数据。
17.4、更新用户的用户名
要使用 ID 更新用户的名称,请在终端中运行以下命令:1
curl -i -XPUT -H "Content-Type: application/json" -d '{"userid": "1", "name": "user1_new"}' localhost:8080/
您应该返回类似于以下内容的 HTTP 响应:
HTTP/1.1 200 OK
Date: Mon, 01 Jan 2020 00:00:00 GMT
Content-Length: 0
要验证用户名是否已更新,请获取 ID 为用户的详细信息。1
在终端中运行以下命令:
curl -i localhost:8080/1
您应该返回类似于以下内容的 HTTP 响应:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Mon, 01 Jan 2020 00:00:00 GMT
Content-Length: 55
{"userid":1,"email":"user1@foo.com","name":"user1_new"}
您可以获取 JSON 形式的用户信息有效负载(请注意更新名称),以及 HTTP 响应元数据。user1_new
要使用 ID 更新用户的名称,请在终端中运行以下命令:42
curl -i -XPUT -H "Content-Type: application/json" -d '{"userid": "42", "name": "user1_new"}' localhost:8080/
您应该返回类似于以下内容的 HTTP 响应:
HTTP/1.1 404 Not Found
Date: Mon, 01 Jan 2020 00:00:00 GMT
Content-Length: 0
正如预期的那样,您得到了一个 HTTP 404,因为数据库中尚不存在具有 ID 的用户。42
17.5、按 ID 检索用户
要删除具有 ID 的用户,请在终端中运行以下命令:1
curl -i -XDELETE localhost:8080/1
您应该返回类似于以下内容的 HTTP 响应:
HTTP/1.1 200 OK
Date: Mon, 01 Jan 2020 00:00:00 GMT
Content-Length: 0
验证表的内容,并确认已删除的用户不存在。在终端中运行以下命令:users
curl -i localhost:8080/
您应该返回类似于以下内容的 HTTP 响应:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Mon, 01 Jan 2020 00:00:00 GMT
Content-Length: 53
[{"userid":2, "email": "user2@foo.com", "name": "user2"}]
正如预期的那样,您只能在响应有效负载中看到,因为刚刚被删除。user2
user1
要获取具有 ID 的用户的详细信息,请在终端中运行以下命令:1
curl -i localhost:8080/1
您应该返回类似于以下内容的 HTTP 响应:
HTTP/1.1 404 Not Found
Date: Mon, 01 Jan 2020 00:00:00 GMT
Content-Length: 0
正如预期的那样,您得到了一个 HTTP 404,因为数据库中尚不存在具有 ID 的用户(刚刚删除了该用户)。1
十八、结论
在本文中,您创建了一个适用于 MySQL 的 Vultr 托管数据库,并使用 MySQL Go 客户端库通过 安全地连接到它。然后,您使用(Go Web框架)构建了一个应用程序,以使用REST API在MySQL表中公开数据。TLS
Gin