首页 >后端开发 >Golang >使用 Go 创建 CRUD API

使用 Go 创建 CRUD API

PHPz
PHPz原创
2024-07-29 13:53:53882浏览

Create a CRUD API with Go

CRUD 操作(创建、读取、更新、删除)是任何 Web 应用程序使用数据库时的基本功能。此示例将向您展示如何使用 Go 创建 CRUD API 并使用 MySQL 作为数据库。

先决条件

  • 去1.21
  • MySQL

设置项目

设置 Go 项目依赖项。

go mod init app
go get github.com/gin-gonic/gin
go get gorm.io/gorm
go get gorm.io/driver/mysql
go get github.com/joho/godotenv

创建名为“example”的测试数据库,并运行database.sql文件导入表和数据。

项目结构

├─ .env
├─ main.go
├─ config
│  └─ db.go
├─ controllers
│  └─ product_controller.go
├─ models
│  └─ product.go
├─ public
│  └─ index.html
└─ router
   └─ router.go

项目文件

.env

此文件包含数据库连接信息。

DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=example
DB_USER=root
DB_PASSWORD=

数据库Go

此文件使用 GORM 设置数据库连接。它声明了一个全局变量 DB 来保存数据库连接实例,以便稍后在我们的应用程序中使用。

package config

import (
    "fmt"
    "os"

    "github.com/joho/godotenv"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "gorm.io/gorm/schema"
)

var DB *gorm.DB

func SetupDatabase() {
    godotenv.Load()
    connection := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=true", os.Getenv("DB_USER"), os.Getenv("DB_PASSWORD"), os.Getenv("DB_HOST"), os.Getenv("DB_PORT"), os.Getenv("DB_DATABASE"))
    db, _ := gorm.Open(mysql.Open(connection), &gorm.Config{NamingStrategy: schema.NamingStrategy{SingularTable: true}})
    DB = db
}

路由器.go

此文件为 Gin Web 应用程序设置路由。它初始化一个路由器,在根 URL 处提供一个静态的 index.html 文件,定义用于 CRUD 操作的 API 路由。

package router

import (
    "app/controllers"

    "github.com/gin-gonic/gin"
)

func SetupRouter() {
    productController := controllers.ProductController{}
    router := gin.Default()
    router.StaticFile("/", "./public/index.html")
    router.Group("/api").
        GET("/products", productController.Index).
        POST("/products", productController.Create).
        GET("/products/:id", productController.Get).
        PUT("/products/:id", productController.Update).
        DELETE("/products/:id", productController.Delete)
    router.Run()
}

产品.go

此文件定义应用程序的产品模型。该模型用于涉及产品的数据库操作。

package models

type Product struct {
    Id int `gorm:"primaryKey;autoIncrement"`
    Name string
    Price float64
}

产品控制器.go

此文件定义了处理传入请求和执行任何 CRUD 操作所需的所有函数。

package controllers

import (
    "app/config"
    "app/models"
    "net/http"
    "strconv"

    "github.com/gin-gonic/gin"
)

type ProductController struct {
}

func (con *ProductController) Index(c *gin.Context) {
    var products []models.Product
    config.DB.Find(&products)
    c.JSON(http.StatusOK, products)
}

func (con *ProductController) Get(c *gin.Context) {
    var product models.Product
    config.DB.First(&product, c.Params.ByName("id"))
    c.JSON(http.StatusOK, product)
}

func (con *ProductController) Create(c *gin.Context) {
    var product models.Product
    c.BindJSON(&product)
    if err := config.DB.Create(&product).Error; err != nil {
        c.AbortWithError(http.StatusBadRequest, err)
        return
    }
    c.JSON(http.StatusOK, product)
}

func (con *ProductController) Update(c *gin.Context) {
    var product models.Product
    c.BindJSON(&product)
    product.Id, _ = strconv.Atoi(c.Params.ByName("id"))
    if err := config.DB.Updates(&product).Error; err != nil {
        c.AbortWithError(http.StatusBadRequest, err)
        return
    }
    c.JSON(http.StatusOK, product)
}

func (con *ProductController) Delete(c *gin.Context) {
    var product models.Product
    if err := config.DB.Delete(&product, c.Params.ByName("id")).Error; err != nil {
        c.AbortWithError(http.StatusBadRequest, err)
        return
    }
    c.Status(http.StatusOK)
}

c.BindJSON() 将请求正文中的 JSON 负载解析为 Go 结构体。

config.DB 用于执行所需数据库操作的 GORM 实例。

c.JSON() 发送带有操作结果和相应 HTTP 状态代码的 JSON 响应。

主程序

该文件是我们应用程序的主要入口点。它将创建并设置 Gin Web 应用程序。

package main

import (
    "app/config"
    "app/router"
)

func main() {
    config.SetupDatabase()
    router.SetupRouter()
}

索引.html

此文件将用于创建用于测试我们的 API 的基本用户界面。

<!DOCTYPE html>
<head>
    <style>
        li {
            margin-bottom: 5px;
        }
        textarea {
            width: 100%;
        }
    </style>
</head>
<body>
    <h1>Example CRUD</h1>
    <ul>
        <li><button onclick="getProducts()">Get Products</button></li>
        <li><button onclick="getProduct()">Get Product</button></li>
        <li><button onclick="createProduct()">Create Product</button></li>
        <li><button onclick="updateProduct()">Update Product</button></li>
        <li><button onclick="deleteProduct()">Delete Product</button></li>
    </ul>
    <textarea id="text_response" rows="20"></textarea>
    <script>
        function showResponse(res) {
            res.text().then(text => {
                let contentType = res.headers.get('content-type')
                if (contentType && contentType.startsWith('application/json')) {
                    text = JSON.stringify(JSON.parse(text), null, 4)
                }
                document.getElementById('text_response').innerHTML = text
            })
        }
        function getProducts() {
            fetch('/api/products').then(showResponse)
        }
        function getProduct() {
            let id = prompt('Input product id')
            fetch('/api/products/' + id).then(showResponse)
        }
        function createProduct() {
            let name = prompt('Input product name')
            let price = parseFloat(prompt('Input product price'))
            fetch('/api/products', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ name, price })
            }).then(showResponse)
        }
        function updateProduct() {
            let id = parseInt(prompt('Input product id to update'))
            let name = prompt('Input new product name')
            let price = parseFloat(prompt('Input new product price'))
            fetch('/api/products/' + id, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ name, price })
            }).then(showResponse)
        }
        function deleteProduct() {
            let id = prompt('Input product id to delete')
            fetch('/api/products/' + id, {
                method: 'DELETE'
            }).then(showResponse)
        }
    </script>
</body>
</html>
  • 许多其他文章都会使用 Postman 作为 HTTP 客户端来测试 API,但本文我将使用 JavaScript 代替。这将帮助您在客户端处理 HTTP 请求时了解更多细节。
  • 为了保持此文件干净且可读,我们将仅使用基本的 HTML 和 JavaScript。这里没有额外的库,例如 CSS Framework 或 Axios。
  • 所有 CRUD 函数都将使用适当的 HTTP 方法来调用 API。
  • showResponse(res) 将格式化 JSON 对象以使其更易于阅读。

运行项目

go run main.go

打开网络浏览器并转到http://localhost:8080

测试

获取所有产品

点击“获取产品”按钮。 API将返回所有产品数据。

Create a CRUD API with Go

通过 ID 获取产品

点击“获取产品”按钮并输入“1”作为产品 ID。该API将返回一个产品数据。

Create a CRUD API with Go

创建产品

点击“创建产品”按钮,输入“test-create”作为产品名称,“100”作为价格。 API 将返回一个新创建的产品。

Create a CRUD API with Go

更新产品

点击“更新产品”按钮,输入“101”作为产品 ID,“test-update”作为名称,“200”作为价格。 API 将返回更新的产品。

Create a CRUD API with Go

删除产品

点击“删除产品”按钮并输入“101”作为产品 ID。 API 不会返回任何内容,这是可以接受的,因为我们不会从 API 返回任何内容。

Create a CRUD API with Go

结论

在本文中,您学习了如何创建和设置 Gin 框架以创建 CRUD API。使用 GORM 作为 ORM 对数据库执行 CRUD 操作。使用 JavaScript 测试我们的 API。我希望您会喜欢这篇文章。

源代码:https://github.com/StackPuz/Example-CRUD-Go

创建 CRUD Web 应用程序:https://stackpuz.com

以上是使用 Go 创建 CRUD API的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn