好吧,我們的 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