用Prisma ORM设置Golang API
Object-Relational Mapper(ORM)是一种在面向对象的程序中存储、检索、更新和删除数据库的技术。ORM简化了我们在面向对象范式中查询和修改数据的方式。
ORM对数据进行建模,而不需要编写和数据库查询。它利用模型类和数据库之间的数据层来管理两者之间的转换。这使得与数据库打交道变得更加容易。与其使用复杂的SQL语句,我们不如通过Prisma这样的ORM来使用面向对象。
Prisma是一个现代的ORM,允许程序员编写类型安全的数据库模式。当然,一切都需要很好的设置,以定义该数据库的样子。在这种情况下,Prisma将开发人员从编写数据库查询中抽象出来,从而确保我们编写安全的数据库访问模式。
Prisma ORM提供Prisma-客户端来设置和编写数据库、数据模型、数据验证以及描述不同数据字段之间的关系。然后,该客户端能够生成查询并连接到所选择的数据库。
为什么Prisma是首选
-
Prisma允许帮助编写类型安全的数据库模型。它为
.prisma文件增加了语法高亮、格式化、自动完成、跳到定义和提示。这有助于你通过提供可靠和完全类型安全的API来避免错误,这些API专门为你的Prisma代码而建。 -
Prisma提供数据库模式迁移。与GitLab等工具一样,Prisma在引入新的变化时都会生成新的版本。这样,每当你当前的模式不能工作时,你总是可以回滚到以前的稳定版本。
-
Prisma提供自省功能。如果你有一个已经存在的数据库,你不必从头开始创建Prisma模型。它还允许你将数据反省到Prisma模式中。例如,如果你在数据库表内已经有一个预定义的模式,你可以反省它,并把它放到Prisma模式中。
-
Prisma允许你将你写在
.prisma文件中的数据模型可视化。它为你提供了一个叫做Prisma studio的GUI,使你能够通过GUI来实现数据的可视化,就像典型的datasets GUI一样。然后,你可以继续插入、创建或更新你的数据。
前提条件
- 安装有最新版本的Node.js。
- 在你的电脑上安装Golang。
- 在你的电脑上安装Postman以测试API端点。
- 有一些Golang的工作知识。
- 对Prisma和Prisma的工作原理有基本了解。
- 在你的电脑上安装Visual Studio Code。
- Prisma扩展应该安装在你的Visual Studio Code中。
设置Go
首先,我们需要设置一个Go程序,并安装库,以使Prisma随时可用。因此,继续创建一个项目文件夹。将其称为prisma-and-go 。然后通过运行以下命令在这个文件夹中初始化你的Go应用程序。
go mod init go-prisma
这个命令将初始化Go应用程序,并创建一个go.mod 文件,用来存储我们将使用的任何包和模块。它还将创建一个本地模块,go-prisma ,我们将用它来导入我们将要创建的任何本地模块。
现在安装软件包,用Prisma设置Go Rest API。我们将使用以下包。
- Prisma Client Go- 一个Prisma生态系统库,提供声明式数据建模、数据访问、可视化数据管理数据库工具和模式迁移。Prisma Client Go是一个查询生成器,可以自动生成查询,允许类型安全的数据库访问和减少模板代码。
要安装这个软件包,请运行。
go get github.com/prisma/prisma-client-go
- Echo- 一个高性能和简约的Go框架,用于创建强大和可扩展的Go RESTful APIs。它是一个高效的HTTP路由器,具有最小的动态内存分配和智能路由优先级。此外,它还提高了速度,以获得更好的用户体验。
要安装这个包,请运行。
go get github.com/labstack/echo/v4
添加v4 ,将安装Echo第4版。
我们还将使用Echo中间件作为一个日志中间件。通过运行以下命令来安装它。
go get github.com/labstack/echo/v4/middleware
设置Prisma
为了将Prisma与Go设置在一起,我们将使用Node.js NPX命令来帮助我们创建Prima模型,将其推送到数据库表示,并设置Go客户端生成。
首先,运行npx prisma init ,利用Prisma客户端来生成Prisma所需的文件。它将创建一个prisma 文件夹,里面有schema.prisma, 和.env 文件。schema.prisma 文件有以下几个块。
-
generator指定要生成的资产,同时产生产生实际查询的数据库类型。 -
datasource包含两个主要参数: 和 。 指定了要使用的数据库。, , , , 和 是例子。providerurlprovidersqlserversqlitemysqlpostgresqlmongodb
参数url 指定了数据库服务器的连接字符串。此外,你的DATABASE URL 可以在.env 文件中指定。DATABASE URL 是与托管你所选择的数据库的服务器的连接字符串。
这些块是为JavaScript生成的。由于我们使用的是Go将对它们进行如下修改。我们将使用SQLite(基于文件的SQL数据库)。这就是你如何设置你的datasource 和generator 。
datasource db {
provider = "sqlite"
url = "file:dev.db"
}
generator db {
provider = "go run github.com/prisma/prisma-client-go"
}
创建一个Prisma模型
模型代表你的应用程序字段的实体。一个模型对应于一个数据库表。让我们开始在SQLite数据库中建模和表示实体。在generator 块下面,添加以下to-dos模型。
model Todos {
id String @id @default(uuid())
complete Boolean @default(false)
name String
updatedAt DateTime @updatedAt
createdAt DateTime @default(now())
}
这个模型将创建一个有五个字段的Todos 数据库表。使用Prisma,每个字段都用名称、数据类型和你想添加到每个字段的值来表示。因此,举例来说,你总是要在SQL表中设置一个唯一的字段。
在这种情况下,我们有一个id,它将使用uuid() ,自动生成。而由于id将总是被添加到每个待办事项中,我们设置@default ,表示这个值将总是以默认的id值创建。
complete 取一个布尔值,要么是真,要么是假。默认情况下,当创建一个新的待办事项时,将创建一个假值。每个字段都有一个数据类型,指定需要的数据。 ,添加一个默认的数据值,即当前时间。createdAt
我们需要执行上述模型以反映SQLite数据库中的Prisma模式。要做到这一点,请运行。
npx Prisma db push
这个命令将在schema 目录内创建一个db 文件夹,以设置配置来加载数据到SQLite数据库。因此,将创建一个dev.db ,以反映数据库表中的设定模式,如下图所示。

这个创建的db ,将是这个数据库的本地模块配置。因此,我们需要运行以下命令来设置go.sum 条目内的模块。
go get go-prisma/prisma/db
现在改变datasource url ,以反映prisma 的模块。
datasource db {
provider = "sqlite"
url = "file:/prisma/dev.db"
}
使用命令npx prisma generate 。这个命令将执行generator 的provider 来设置prisma-client-go 。
用Go和Echo建立RESTful API
我们设置了一个to-dos模式,并将其导出到一个典型的数据库。然后,让我们创建一个简单的Restful API,演示如何将加载的Prisma与Go应用程序一起使用。
使用Echo设置处理程序
你需要使用不同的HTTP方法进行不同的操作来设置API。最常见的HTTP方法是GET 、POST 、PUT 、DELETE 。
这些HTTP方法有特定的含义。通常情况下,你使用正确的方法进行适当的操作,如获取、添加、更新和删除数据。所以,让我们编写这些编写方法,并创建一个REST。
在你的项目目录下,创建一个handler 文件夹,在该文件夹内,创建一个to-dos.go 文件,并按照以下步骤操作。
第1步:创建一个包并导入模块
package handler
import (
"context"
"go-prisma/prisma/db"
"net/http"
"github.com/labstack/echo/v4"
)
这个代码块将创建一个包handler ,我们将在本地模块系统中使用。我们也会导入我们需要设置处理程序的库。
这个导入包括Go的核心模块,如context 和net/http 。同时,导入生成的Prism模块以访问Prisma模式结构。此外,为了创建不同的HTTP方法,导入已安装的Echo包。
第2步:添加结构
type TodosHandler struct {
client *db.PrismaClient
}
// TODO structure
type TodosResponse struct {
db.TodosModel
}
TodosHandler 将建立一个 引擎,创建引擎盖下发生的事情的抽象。这样查询引擎可以生成并发送请求到 。PrismaClient PrismaClient
TodosResponse 创建一个代表 模型的 ,以及一个用于访问字段和方法的包装器。json:"Todos" TodosModel
第3步:创建一个函数来执行 "TodosHandler"。
func NewTodoHandler(client *db.PrismaClient) *TodosHandler {
return &TodosHandler{client}
}
相对于模型方法,Prisma提供了Prisma相关的方法。所以现在我们可以开始实现这些Prisma相关的方法,以获得相关的响应。
第4步:创建一个获取函数
func (h *TodosHandler) ShowAll(c echo.Context) error {
todos, err := h.client.Todos.FindMany().Exec(context.Background())
if err != nil {
return c.String(http.StatusInternalServerError, "error getting Todos")
}
return c.JSON(http.StatusOK, todos)
}
正如我们所说,Prisma提供了Prisma相关的方法。我们将使用FindMany() Prisma方法来获取这些to-dos。PrismaClient 引擎将创建一个抽象的引擎下发生的事情,然后返回可用的to-dos列表,如果这个执行环境失败,则返回一个错误信息。
第5步:创建获取单个待办事项的函数
func (h *TodosHandler) Show(c echo.Context) error {
todo, err := h.client.Todos.FindUnique(db.Todos.ID.Equals(c.Param("id"))).Exec(context.Background())
if err != nil {
return c.String(http.StatusInternalServerError, err.Error())
}
return c.JSON(http.StatusOK, todo)
}
要获得一个单一的待办事项,使用FindUnique() ,它将执行待办事项的id字段参数,并返回与提供的id参数相等的待办事项值。
第6步:创建一个添加新待办事项的函数
func (h *TodosHandler) Create(c echo.Context) error {
var todo db.TodosModel
if err := c.Bind(&todo); err != nil {
return c.String(http.StatusInternalServerError, err.Error())
}
created, err := h.client.Todos.CreateOne(
db.Todos.Name.Set(todo.Name),
).Exec(context.Background())
if err != nil {
return c.String(http.StatusInternalServerError, err.Error())
}
return c.JSON(http.StatusOK, created)
}
要使用PrismaClient 创建一个新条目,请使用CreateOne() 函数。PrismaClient 引擎将插入一个新条目,然后返回新添加的待办事项的值。
尝试创建其他处理程序来执行UPDATE和DELETE等方法。
使用Echo设置路由
为了执行上述所有的处理函数,我们需要用相应的HTTP方法设置路由。例如,为了获取一个待办事项,我们需要设置一个路由,执行一个GET请求,返回可用的待办事项的列表。
在你的项目目录下创建一个router 文件夹,在该文件夹内,创建一个to-dos.go 文件,并按照以下步骤操作。
第1步:创建一个包并导入模块
package router
import (
"github.com/labstack/echo/v4"
"go-prisma/handler"
"go-prisma/prisma/db"
)
这个代码块将创建一个包router ,我们将在本地模块系统中使用。我们还导入库来设置一个router 。这个导入包括生成的Prisma模块来访问Prisma模式结构,以及handler 模块来访问处理函数。我们还需要Echo包来创建不同的HTTP方法。
第2步:创建一个路由器函数
func TodoRouter(e *echo.Echo, dbClient *db.PrismaClient) {
todoHandler := handler.NewTodoHandler(dbClient)
g := e.Group("/todos/")
g.GET("", todoHandler.ShowAll)
g.GET(":id", todoHandler.Show)
g.POST("", todoHandler.Create)
}
在这里,我们只是设置一个基本的路由,它将根据被执行的方法来使用。同时,指定一个需要参数的端点,如id值。
设置服务器
为了设置我们到目前为止所建立的一切,我们需要设置一个本地服务器,我们将用它来访问API。我们使用Gomain() 函数,在Go应用程序运行时执行。下面是我们要做的事情。
第3步:创建一个包并导入模块
package main
import (
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"go-prisma/prisma/db"
"go-prisma/router"
"log"
)
上面的代码片断将创建Gomain 模块。我们还导入我们所创建的本地模块,包括router 和prisma/db 模块。我们还需要Echo包来访问不同的HTTP方法和Echo中间件以及log来实现HTTP日志。
第4步:创建Go的主函数
func main() {
e := echo.New()
e.Use(middleware.Logger())
client := db.NewClient()
if err := client.Prisma.Connect(); err != nil {
log.Fatal(err)
}
defer func() {
if err := client.Prisma.Disconnect(); err != nil {
panic(err)
}
}()
router.TodoRouter(e, client)
log.Print(e.Routes())
e.Logger.Fatal(e.Start(":8000"))
}
在这里,我们使用一个echo 实例来设置一个记录器。每当一个HTTP方法被执行时,它就会记录并打印出一个HTTP状态。
为了访问PrismaClient ,我们使用与Prisma相关的方法,如Connect() ,建立与Prisma引擎的连接,以及Disconnect() ,从运行中的Prisma实例中释放资源。
一旦与Prisma的连接可用,就执行我们先前设置的路由,并将服务器映射到一个端口号。
测试应用程序
服务器已经准备好了,我们可以运行它来测试Go和Prisma是否设置好了执行to-dos。使用命令go run main.go 来运行Go应用程序。这个命令将使用Echo启动Go服务器。

一旦服务器启动并运行,打开Postman并测试不同的HTTP方法。
我们将从创建一个新的待办事项开始。但是,首先,前往Postman,使用URLhttp://localhost:8080/todos/ 创建一个POST方法,如下图所示。

点击发送来执行上述方法,添加的待办事项将被添加到SQLite数据库中,并由Postman打印出来,如下图所示。

你可以继续尝试添加几个新的待办事项。另外,请注意,每次你执行一个方法时,都会在你的命令行控制台注册一个日志。

一旦你添加了一个待办事项列表,你可以发送一个GET请求来获取这些待办事项。

你也可以用它的id作为请求参数来获取单个待办事项,即http://localhost:8080/todos/:id ,其中:id 是你想获取的待办事项的id值。
总结
Prisma的美妙之处在于,它使数据库的工作感觉非常直观和直接,从数据建模、运行、迁移、编写查询,以及与API的集成。