我已经在golang中构建了一个CRUD应用程序,遵循本教程:https://www.youtube.com/live/aLVJY-1dKz8?feature=shared
我已经连接到数据库并使用PgAdmin创建了postgres表。
服务使用Docker Compose启动。
但是 Postman 的请求不起作用。
我收到“错误:socket hang up”on postman和“dial tcp 127.0.0.1:5432:connect:connection refused”。
以下是此应用程序的两个文件:
docker-compose.yml
version: '3'
services:
dicane-service:
build:
context: ./../dicane-service
dockerfile: ./../dicane-service/dicane-service.dockerfile
restart: always
ports:
- "8000:8000"
deploy:
mode: replicated
replicas: 1
environment:
DSN: "host=postgres port=5432 user=postgres password=password dbname=postgres sslmode=disable timezone=UTC connect_timeout=5"
depends_on:
- postgres
postgres:
image: 'postgres:14.0'
ports:
- "5432:5432"
restart: always
deploy:
mode: replicated
replicas: 1
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: postgres
volumes:
- ./db-data/postgres/:/var/lib/postgresql/data/
pg-admin:
image: dpage/pgadmin4:7
environment:
- [email protected]
- PGADMIN_DEFAULT_PASSWORD=password
- PGADMIN_LISTEN_PORT=5050
ports:
- "5050:5050"
main.go
package main
import (
"database/sql"
"encoding/json"
"log"
"net/http"
"os"
"time"
"github.com/gorilla/mux"
_ "github.com/lib/pq"
)
type Sale struct {
Sale_id string `json:"sale_id"`
removed the other fields to make this code sample smaller...
Images []string `json:"images"`
}
func main() {
// connect to database
db, err := sql.Open("postgres", os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatal(err)
}
defer db.Close()
//create router
router := mux.NewRouter()
router.HandleFunc("/sales", getSales(db)).Methods("GET")
router.HandleFunc("/sales/{id}", getSale(db)).Methods("GET")
router.HandleFunc("/sales", createSale(db)).Methods("POST")
router.HandleFunc("/sales/{id}", updateSale(db)).Methods("PUT")
router.HandleFunc("/sales/{id}", deleteSale(db)).Methods("DELETE")
// start server
log.Fatal(http.ListenAndServe(":8000", jsonContentTypeMiddleware(router)))
}
func jsonContentTypeMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
next.ServeHTTP(w, r)
})
}
func getSales(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
rows, err := db.Query("SELECT * FROM sales")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
sales := []Sale{}
for rows.Next() {
var sale Sale
if err := rows.Scan(
&sale.Sale_id,
... removed the other fields to make this code sample smaller...
&sale.Images,
); err != nil {
log.Fatal(err)
}
sales = append(sales, sale)
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
json.NewEncoder(w).Encode(sales)
}
}
func getSale(db *sql.DB) http.HandlerFunc {
print("getSale")
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["sale_id"]
var sale Sale
err := db.QueryRow("SELECT * FROM sales WHERE sale_id = $1", id).Scan(
&sale.Sale_id,
... removed the other fields to make this code sample smaller...
&sale.Images,
)
if err != nil {
log.Fatal(err)
}
json.NewEncoder(w).Encode(sale)
}
}
func createSale(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var sale Sale
json.NewDecoder(r.Body).Decode(&sale)
err := db.QueryRow("INSERT INTO sales ("+
... removed the other fields to make this code sample smaller...
" images)"+
" VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $21, $22, $23)"+
" RETURNING sale_id",
... removed the other fields to make this code sample smaller...
).Scan(&sale.Sale_id)
if err != nil {
log.Fatal(err)
}
json.NewEncoder(w).Encode(sale)
}
}
func updateSale(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var sale Sale
json.NewDecoder(r.Body).Decode(&sale)
vars := mux.Vars(r)
saleId := vars["sale_id"]
_, err := db.Exec("UPDATE sales SET"+
... removed the other fields to make this code sample smaller...
)+"WHERE id = $24",
... removed the other fields to make this code sample smaller...
saleId,
)
if err != nil {
log.Fatal(err)
}
json.NewEncoder(w).Encode(sale)
}
}
func deleteSale(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
saleId := vars["sale_id"]
var sale Sale
err := db.QueryRow("SELECT * FROM sales WHERE sale_id = $1", saleId).Scan(
&sale.Sale_id,
... removed the other fields to make this code sample smaller
&sale.Images,
)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
} else {
_, err := db.Exec("DELETE FROM sales WHERE sale_id = $1", saleId)
if err != nil {
//todo : fix error handling
w.WriteHeader(http.StatusNotFound)
return
}
json.NewEncoder(w).Encode("User deleted")
}
}
}
1条答案
按热度按时间vlju58qv1#
我在
os.Getenv(DATABASE_URL)
函数中得到了错误的值。它应该与
docker-compose.yml
中声明的环境变量相匹配,该环境变量为:我刚刚从
DSN
改为DATABASE_URL
。现在它正在工作:)