”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 将 Go API 连接到 PostgreSQL 数据库

将 Go API 连接到 PostgreSQL 数据库

发布于2024-11-03
浏览:809

Connecting Your Go API to a PostgreSQL Database

好吧,我们的 Go API 已经开始运行了,但现在是我们给它一些长期记忆的时候了。本周,我们将 API 连接到 PostgreSQL,这样您就可以存储所有宝贵的数据,而不会在关闭应用程序时丢失它们。相信我,您的用户会感谢您。

为什么选择 PostgreSQL?

PostgreSQL 或简称“Postgres”,是真正的数据库。这就是它成为最受欢迎的数据库的原因:

  1. 功能丰富:无论您想要存储纯旧文本、JSON,甚至是复杂的地理数据,Postgres 都能满足您的需求。它还具有完全的 ACID 合规性(阅读:它使您的数据保持一致和安全)和足够奇特的查询选项,可以让任何数据迷微笑。

  2. 开源和免费:没错,Postgres 是完全免费和开源的。另外,它有一个活跃的社区,不断改进它,所以你永远不必担心它会过时。

  3. 像专业人士一样扩展:无论您是构建小型应用程序还是大型数据处理企业服务,Postgres 都可以处理。它的设计是可扩展的,具有并行查询执行和优化魔法,以保持事物顺利运行。

  4. 像坦克一样建造:经过数十年的发展,Postgres 坚如磐石。它会定期更新,具有大量安全功能,并被 Apple 和 Netflix 等巨头用于制作。

明白了吗?太酷了,让我们将它连接到 Go API 并开始使用一些数据库魔法!

步骤 0:设置 PostgreSQL

如果您尚未安装 PostgreSQL,请在此处获取。然后让我们启动它:

  1. 连接到 PostgreSQL:

   psql -U postgres


  1. 创建数据库:

   CREATE DATABASE bookdb;


  1. 为我们的书籍设置一个桌子

   \c bookdb;
   CREATE TABLE books (
       id SERIAL PRIMARY KEY,
       title VARCHAR(255) NOT NULL,
       author VARCHAR(255) NOT NULL
   );


现在您已经准备好了一个新的数据库。是时候去和它说话了!

第1步:连接Go到PostgreSQL

我们为此使用 pgx 库。它速度快、重量轻,并且可以完成工作。


go get github.com/jackc/pgx/v5


打开 main.go 文件并添加以下代码以设置与数据库的连接:


var db *pgxpool.Pool

func connectDB() *pgxpool.Pool {
    url := "postgres://postgres:yourpassword@localhost:5432/bookdb"
    config, err := pgxpool.ParseConfig(url)
    if err != nil {
        log.Fatalf("Unable to parse DB config: %v\n", err)
    }

    dbpool, err := pgxpool.NewWithConfig(context.Background(), config)
    if err != nil {
        log.Fatalf("Unable to connect to database: %v\n", err)
    }

    return dbpool
}


将您的密码替换为您的 PostgreSQL 密码。该函数连接到我们的 bookdb 数据库并返回一个连接池,这基本上意味着我们的应用程序将有一堆可重用的连接可供使用。效率啊宝贝! ?

第2步:更新主要功能

让我们确保我们的数据库连接在我们的服务器启动时启动:


func main() {
    db = connectDB()
    defer db.Close()

    // Initialize router and define routes here (as before)
}


第 3 步:CRUD 操作 – 引入数据

好吧,让我们添加一些函数来获取、创建和管理数据库中的书籍。

获取所有书籍


func getBooks(w http.ResponseWriter, r *http.Request) {
    rows, err := db.Query(context.Background(), "SELECT id, title, author FROM books")
    if err != nil {
        http.Error(w, "Database error", http.StatusInternalServerError)
        return
    }
    defer rows.Close()

    var books []Book
    for rows.Next() {
        var book Book
        err := rows.Scan(&book.ID, &book.Title, &book.Author)
        if err != nil {
            http.Error(w, "Error scanning row", http.StatusInternalServerError)
            return
        }
        books = append(books, book)
    }

    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(books)
}


添加新书


func createBook(w http.ResponseWriter, r *http.Request) {
    var book Book
    err := json.NewDecoder(r.Body).Decode(&book)
    if err != nil {
        http.Error(w, "Bad request", http.StatusBadRequest)
        return
    }

    _, err = db.Exec(context.Background(), "INSERT INTO books (title, author) VALUES ($1, $2)", book.Title, book.Author)
    if err != nil {
        http.Error(w, "Error inserting book", http.StatusInternalServerError)
        return
    }

    w.WriteHeader(http.StatusCreated)
    json.NewEncoder(w).Encode(book)
}


步骤 4:使用中间件保护路由

我们希望确保只有经过身份验证的用户才能访问我们新的数据库驱动的端点。使用第 2 周的身份验证中间件,一切就都准备好了!


func main() {
    db = connectDB()
    defer db.Close()

    r := mux.NewRouter()

    r.HandleFunc("/login", login).Methods("POST")
    r.Handle("/books", authenticate(http.HandlerFunc(getBooks))).Methods("GET")
    r.Handle("/books", authenticate(http.HandlerFunc(createBook))).Methods("POST")

    fmt.Println("Server started on port :8000")
    log.Fatal(http.ListenAndServe(":8000", r))
}


测试一下

让我们测试一下这个东西:

  1. 添加新书

   curl -X POST http://localhost:8000/books -d '{"title": "1984", "author": "George Orwell"}' -H "Content-Type: application/json"


  1. 获取所有书籍:

   curl http://localhost:8000/books


繁荣!您已经有了一个带有 PostgreSQL 的 Go API,准备好处理一些真实数据。

接下来是什么?

下次,我们将使用一些用于日志记录和错误处理的自定义中间件使我们的 API 更加流畅。更多精彩敬请期待!

版本声明 本文转载于:https://dev.to/neelp03/connecting-your-go-api-to-a-postgresql-database-39?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 在Pandas中如何将年份和季度列合并为一个周期列?
    在Pandas中如何将年份和季度列合并为一个周期列?
    pandas data frame thing commans date lay neal and pree pree'和pree pree pree”,季度 2000 q2 这个目标是通过组合“年度”和“季度”列来创建一个新列,以获取以下结果: [python中的concate...
    编程 发布于2025-05-19
  • Java为何无法创建泛型数组?
    Java为何无法创建泛型数组?
    通用阵列创建错误 arrayList [2]; JAVA报告了“通用数组创建”错误。为什么不允许这样做?答案:Create an Auxiliary Class:public static ArrayList<myObject>[] a = new ArrayList<myO...
    编程 发布于2025-05-19
  • Spark DataFrame添加常量列的妙招
    Spark DataFrame添加常量列的妙招
    在Spark Dataframe ,将常数列添加到Spark DataFrame,该列具有适用于所有行的任意值的Spark DataFrame,可以通过多种方式实现。使用文字值(SPARK 1.3)在尝试提供直接值时,用于此问题时,旨在为此目的的column方法可能会导致错误。 df.withCo...
    编程 发布于2025-05-19
  • Android如何向PHP服务器发送POST数据?
    Android如何向PHP服务器发送POST数据?
    在android apache httpclient(已弃用) httpclient httpclient = new defaulthttpclient(); httppost httppost = new httppost(“ http://www.yoursite.com/script.p...
    编程 发布于2025-05-19
  • 为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    网格超过身体,用100%grid-template-columns 为什么在grid-template-colms中具有100%的显示器,当位置设置为设置的位置时,grid-template-colly修复了?问题: 考虑以下CSS和html: class =“ snippet-code”> g...
    编程 发布于2025-05-19
  • 在C#中如何高效重复字符串字符用于缩进?
    在C#中如何高效重复字符串字符用于缩进?
    在基于项目的深度下固定字符串时,重复一个字符串以进行凹痕,很方便有效地有一种有效的方法来返回字符串重复指定的次数的字符串。使用指定的次数。 constructor 这将返回字符串“ -----”。 字符串凹痕= new String(' - ',depth); console.Wr...
    编程 发布于2025-05-19
  • 如何使用Regex在PHP中有效地提取括号内的文本
    如何使用Regex在PHP中有效地提取括号内的文本
    php:在括号内提取文本在处理括号内的文本时,找到最有效的解决方案是必不可少的。一种方法是利用PHP的字符串操作函数,如下所示: 作为替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式来搜索特...
    编程 发布于2025-05-19
  • 如何解决由于Android的内容安全策略而拒绝加载脚本... \”错误?
    如何解决由于Android的内容安全策略而拒绝加载脚本... \”错误?
    Unveiling the Mystery: Content Security Policy Directive ErrorsEncountering the enigmatic error "Refused to load the script..." when deployi...
    编程 发布于2025-05-19
  • Java中Lambda表达式为何需要“final”或“有效final”变量?
    Java中Lambda表达式为何需要“final”或“有效final”变量?
    Lambda Expressions Require "Final" or "Effectively Final" VariablesThe error message "Variable used in lambda expression shou...
    编程 发布于2025-05-19
  • 如何避免Go语言切片时的内存泄漏?
    如何避免Go语言切片时的内存泄漏?
    ,a [j:] ...虽然通常有效,但如果使用指针,可能会导致内存泄漏。这是因为原始的备份阵列保持完整,这意味着新切片外部指针引用的任何对象仍然可能占据内存。 copy(a [i:] 对于k,n:= len(a)-j i,len(a); k
    编程 发布于2025-05-19
  • 如何使用PHP从XML文件中有效地检索属性值?
    如何使用PHP从XML文件中有效地检索属性值?
    从php PHP陷入困境。使用simplexmlelement :: attributes()函数提供了简单的解决方案。此函数可访问对XML元素作为关联数组的属性: - > attributes()为$ attributeName => $ attributeValue){ echo ...
    编程 发布于2025-05-19
  • PHP未来:适应与创新
    PHP未来:适应与创新
    PHP的未来将通过适应新技术趋势和引入创新特性来实现:1)适应云计算、容器化和微服务架构,支持Docker和Kubernetes;2)引入JIT编译器和枚举类型,提升性能和数据处理效率;3)持续优化性能和推广最佳实践。 引言在编程世界中,PHP一直是网页开发的中流砥柱。作为一个从1994年就开始发展...
    编程 发布于2025-05-19
  • 为什么我的CSS背景图像出现?
    为什么我的CSS背景图像出现?
    故障排除:CSS背景图像未出现 ,您的背景图像尽管遵循教程说明,但您的背景图像仍未加载。图像和样式表位于相同的目录中,但背景仍然是空白的白色帆布。而不是不弃用的,您已经使用了CSS样式: bockent {背景:封闭图像文件名:背景图:url(nickcage.jpg); 如果您的html,css...
    编程 发布于2025-05-19
  • PHP阵列键值异常:了解07和08的好奇情况
    PHP阵列键值异常:了解07和08的好奇情况
    PHP数组键值问题,使用07&08 在给定数月的数组中,键值07和08呈现令人困惑的行为时,就会出现一个不寻常的问题。运行print_r($月)返回意外结果:键“ 07”丢失,而键“ 08”分配给了9月的值。此问题源于PHP对领先零的解释。当一个数字带有0(例如07或08)的前缀时,PHP将其...
    编程 发布于2025-05-19
  • 如何有效地转换PHP中的时区?
    如何有效地转换PHP中的时区?
    在PHP 利用dateTime对象和functions DateTime对象及其相应的功能别名为时区转换提供方便的方法。例如: //定义用户的时区 date_default_timezone_set('欧洲/伦敦'); //创建DateTime对象 $ dateTime = ne...
    编程 发布于2025-05-19

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3