好吧,我们的 Go API 已经开始运行了,但现在是我们给它一些长期记忆的时候了。本周,我们将 API 连接到 PostgreSQL,这样您就可以存储所有宝贵的数据,而不会在关闭应用程序时丢失它们。相信我,您的用户会感谢您。
PostgreSQL 或简称“Postgres”,是真正的数据库。这就是它成为最受欢迎的数据库的原因:
功能丰富:无论您想要存储纯旧文本、JSON,甚至是复杂的地理数据,Postgres 都能满足您的需求。它还具有完全的 ACID 合规性(阅读:它使您的数据保持一致和安全)和足够奇特的查询选项,可以让任何数据迷微笑。
开源和免费:没错,Postgres 是完全免费和开源的。另外,它有一个活跃的社区,不断改进它,所以你永远不必担心它会过时。
像专业人士一样扩展:无论您是构建小型应用程序还是大型数据处理企业服务,Postgres 都可以处理。它的设计是可扩展的,具有并行查询执行和优化魔法,以保持事物顺利运行。
像坦克一样建造:经过数十年的发展,Postgres 坚如磐石。它会定期更新,具有大量安全功能,并被 Apple 和 Netflix 等巨头用于制作。
明白了吗?太酷了,让我们将它连接到 Go API 并开始使用一些数据库魔法!
如果您尚未安装 PostgreSQL,请在此处获取。然后让我们启动它:
psql -U postgres
CREATE DATABASE bookdb;
\c bookdb; CREATE TABLE books ( id SERIAL PRIMARY KEY, title VARCHAR(255) NOT NULL, author VARCHAR(255) NOT NULL );
现在您已经准备好了一个新的数据库。是时候去和它说话了!
我们为此使用 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 数据库并返回一个连接池,这基本上意味着我们的应用程序将有一堆可重用的连接可供使用。效率啊宝贝! ?
让我们确保我们的数据库连接在我们的服务器启动时启动:
func main() { db = connectDB() defer db.Close() // Initialize router and define routes here (as before) }
好吧,让我们添加一些函数来获取、创建和管理数据库中的书籍。
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) }
我们希望确保只有经过身份验证的用户才能访问我们新的数据库驱动的端点。使用第 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)) }
让我们测试一下这个东西:
curl -X POST http://localhost:8000/books -d '{"title": "1984", "author": "George Orwell"}' -H "Content-Type: application/json"
curl http://localhost:8000/books
繁荣!您已经有了一个带有 PostgreSQL 的 Go API,准备好处理一些真实数据。
下次,我们将使用一些用于日志记录和错误处理的自定义中间件使我们的 API 更加流畅。更多精彩敬请期待!
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3