Iris是一个快速轻巧的Web框架,可提供丰富的功能和高性能引擎。 PostgreSQL是一个强大而可靠的关系数据库系统,支持高级数据类型和功能。他们一起可以为构建现代网络应用程序构成坚实的基础。
但是如何以简单且类型的安全方式连接iris和PostgresQL?如何在不编写太多样板代码的情况下执行通用数据库操作?您如何以一致的方式处理交易,模式创建,查询跟踪和错误处理?
答案是PG中间件,是IRIS的软件包,可轻松且可安全地访问PostgreSQL数据库。在本文中,我们将向您展示如何使用PG中间件来创建一个简单的REST API来管理客户。
什么是PG中间件?
PG中间件是IRIS Web框架的软件包,可轻松且可安全地访问PostgreSQL数据库。它具有以下功能:
- 它支持PostgreSQL 9.5及以上。
- 它在引擎盖下使用pg软件包和pgx驱动程序。
- 它支持交易,架构创建和验证,查询跟踪和错误处理。
- 它允许使用模式对象注册自定义类型和表模型。
- 它为常见的Crud操作提供了一个通用的存储库接口。
如何安装PG中间件?
要安装PG中间件,您需要使用以下命令:
go get github.com/iris-contrib/middleware/pg@master
如何使用PG中间件?
要使用PG中间件,您需要遵循以下步骤:
- 在您的代码中导入包:
import (
"github.com/kataras/iris/v12"
"github.com/iris-contrib/middleware/pg"
)
- 将数据库表模型定义为带有
pg
标签的结构:
// The Customer database table model.
type Customer struct {
ID string `json:"id" pg:"type=uuid,primary"`
Name string `json:"name" pg:"type=varchar(255)"`
}
json
标签定义了结构字段是如何编码或解码为JSON的。 pg
标签定义了如何将结构字段映射到数据库表列。您可以使用pg
标签指定列类型,约束,索引和其他选项。在pg存储库中阅读更多信息。
- 创建一个模式对象并注册您的模型:
schema := pg.NewSchema()
schema.MustRegister("customers", Customer{})
模式对象用于存储数据库表和模型的元数据。您需要使用MustRegister
方法向模型对象注册模型。第一个参数是表名,第二个参数是模型类型。
- 使用模式和数据库选项创建PG中间件实例:
opts := pg.Options{
Host: "localhost",
Port: 5432,
User: "postgres",
Password: "admin!123",
DBName: "test_db",
Schema: "public",
SSLMode: "disable",
Transactional: true,
Trace: true,
CreateSchema: true,
CheckSchema: true,
ErrorHandler: func(ctx iris.Context, err error) {
ctx.StopWithError(iris.StatusInternalServerError, err)
},
}
p := pg.New(schema, opts)
选项结构定义用于连接到数据库并使用中间件功能的配置参数。您需要指定主机,端口,用户,密码,DBNAME,模式和SSLMode字段来建立连接。您还可以启用或禁用交易功能,该功能将每个请求处理程序包装在数据库事务中。您还可以启用或禁用跟踪功能,该功能记录了中间件执行的每个查询。您还可以启用或禁用CreateSchema功能,如果数据库中不存在,则可以创建该架构。您还可以启用或禁用CheckSchema功能,该功能检查架构是否缺少表和列,并报告任何差异。您还可以提供一个错误Handler函数,该功能处理中间件执行期间发生的任何错误。
New
函数使用给定的模式和选项创建一个新的PG中间件实例。
- 将中间件处理程序附加到您的Iris应用程序或路线上:
app := iris.New()
postgresMiddleware := newPostgresMiddleware()
{
customerAPI := app.Party("/api/customer", postgresMiddleware)
customerAPI.Post("/", createCustomer)
customerAPI.Get("/{id:uuid}", getCustomer)
customerAPI.Put("/{id:uuid}", updateCustomer)
customerAPI.Delete("/{id:uuid}", deleteCustomer)
}
中间软件处理程序是一个函数,该函数采用虹膜上下文并调用链中的下一个处理程序。您可以使用Use
或Party
方法将中间件处理程序连接到Iris应用程序或路由。在此示例中,我们为客户API创建一个子路线,并将中间件处理程序应用于它。
- 使用
pg.DB
或pg.Repository
package-level函数访问处理程序中的数据库实例或存储库接口:
func createCustomer(ctx iris.Context) {
var payload = struct {
Name string `json:"name"`
}{}
err := ctx.ReadJSON(&payload)
if err != nil {
ctx.StopWithError(iris.StatusBadRequest, err)
return
}
// Get the current database instance through pg.DB middleware package-level function.
// db := pg.DB(ctx)
// [Work with db instance...]
// OR, initialize a new repository of Customer type and work with it (type-safety).
customers := pg.Repository[Customer](ctx)
// Insert a new Customer.
customer := Customer{
Name: payload.Name,
}
err = customers.InsertSingle(ctx, customer, &customer.ID)
if err != nil {
ctx.StopWithError(iris.StatusInternalServerError, err)
return
}
// Display the result ID.
ctx.StatusCode(iris.StatusCreated)
ctx.JSON(iris.Map{"id": customer.ID})
}
func getCustomer(ctx iris.Context) {
// Get the id from the path parameter.
id := ctx.Params().Get("id")
// Get the repository of Customer type through pg.Repository middleware package-level function.
customers := pg.Repository[Customer](ctx)
// Get the customer by the id.
customer, err := customers.SelectByID(ctx, id)
if err != nil {
if pg.IsErrNoRows(err) {
ctx.StopWithStatus(iris.StatusNotFound)
} else {
ctx.StopWithError(iris.StatusInternalServerError, err)
}
return
}
// Display the retrieved Customer.
ctx.JSON(customer)
}
func updateCustomer(ctx iris.Context) {
// Get the id from the path parameter.
id := ctx.Params().Get("id")
var payload = struct {
Name string `json:"name"`
}{}
err := ctx.ReadJSON(&payload)
if err != nil {
ctx.StopWithError(iris.StatusBadRequest, err)
return
}
// Get the repository of Customer type through pg.Repository middleware package-level function.
customers := pg.Repository[Customer](ctx)
// Update the customer by the id and name.
customer := Customer{
ID: id,
Name: payload.Name,
}
_, err = customers.UpdateOnlyColumns(ctx, []string{"name"}, customer)
// OR customers.Update(ctx, customer)
if err != nil {
if pg.IsErrNoRows(err) {
ctx.StopWithStatus(iris.StatusNotFound)
} else {
ctx.StopWithError(iris.StatusInternalServerError, err)
}
return
}
// Display a success message.
ctx.StatusCode(iris.StatusOK)
ctx.JSON(iris.Map{"message": "Customer updated successfully"})
}
func deleteCustomer(ctx iris.Context) {
// Get the id from the path parameter.
id := ctx.Params().Get("id")
// Get the repository of Customer type through pg.Repository middleware package-level function.
customers := pg.Repository[Customer](ctx)
// Delete the customer by the id.
_, err := customers.Delete(ctx, Customer{ID: id})
if err != nil {
if pg.IsErrNoRows(err) {
ctx.StopWithStatus(iris.StatusNotFound)
} else {
ctx.StopWithError(iris.StatusInternalServerError, err)
}
return
}
// Display a success message.
ctx.StatusCode(iris.StatusOK)
ctx.JSON(iris.Map{"message": "Customer deleted successfully"})
}
pg.DB
函数返回与虹膜上下文关联的当前数据库实例。您可以使用此实例使用pg
软件包API执行任何数据库操作。 pg.Repository
函数返回与Iris上下文关联的给定模型类型的通用存储库接口。您可以使用此接口使用类型安全方法执行常见的CRUD操作。在此示例中,我们使用存储库接口插入和选择客户。
如何运行示例?
要运行示例,您需要:
- 克隆PG middleware repository并导航到
_examples/basic
文件夹。 - 使用
go mod tidy
安装依赖项。 - 启动一个PostgreSQL Server并创建一个名为
test_db
的数据库。 - 使用
go run main.go
运行main.go文件。 - 使用像Postman或curl这样的工具测试API端点:
# Create a new customer
curl -X POST -H "Content-Type: application/json" -d '{"name":"Alice"}' http://localhost:8080/api/customer
# Get a customer by id
curl -X GET http://localhost:8080/api/customer/1f8c9a7c-6b7c-4f0e-8a1d-9f2a9c3b7b8e
# Update a customer by id
curl -X PUT -H "Content-Type: application/json" -d '{"name":"Bob"}' http://localhost:8080/api/customer/1f8c9a7c-6b7c-4f0e-8a1d-9f2a9c3b7b8e
# Delete a customer by id
curl -X DELETE http://localhost:8080/api/customer/1f8c9a7c-6b7c-4f0e-8a1d-9f2a9c3b7b8e
结论
在本文中,我们向您展示了如何使用PG中间件以简单且类型的安全方式连接Iris和PostgreSQL。我们还展示了如何使用PG中间件功能,例如交易,架构创建和验证,查询跟踪和错误处理。我们还展示了如何使用PG中间件来创建一个简单的REST API来管理客户。
我们希望您发现PG中间件有用且易于使用。如果您有任何反馈或疑问,请随时在GitHub上打开问题或提取请求。谢谢您的阅读!ð