- Go backend with PostgreSQL connection - Next.js frontend with TypeScript - Docker Compose for local development - Woodpecker CI pipeline for build and push - Kubernetes manifests with Kustomize - ArgoCD application for GitOps deployment Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
94 lines
2.1 KiB
Go
94 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"database/sql"
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
|
|
_ "github.com/lib/pq"
|
|
)
|
|
|
|
type Response struct {
|
|
Message string `json:"message"`
|
|
DBStatus string `json:"db_status"`
|
|
}
|
|
|
|
var db *sql.DB
|
|
|
|
func main() {
|
|
// PostgreSQL connection
|
|
dbHost := getEnv("DB_HOST", "localhost")
|
|
dbPort := getEnv("DB_PORT", "5432")
|
|
dbUser := getEnv("DB_USER", "postgres")
|
|
dbPassword := getEnv("DB_PASSWORD", "postgres")
|
|
dbName := getEnv("DB_NAME", "hellodb")
|
|
|
|
connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
|
|
dbHost, dbPort, dbUser, dbPassword, dbName)
|
|
|
|
var err error
|
|
db, err = sql.Open("postgres", connStr)
|
|
if err != nil {
|
|
log.Printf("Warning: Could not connect to database: %v", err)
|
|
} else {
|
|
defer db.Close()
|
|
}
|
|
|
|
// HTTP handlers
|
|
http.HandleFunc("/api/hello", corsMiddleware(helloHandler))
|
|
http.HandleFunc("/api/health", corsMiddleware(healthHandler))
|
|
|
|
port := getEnv("PORT", "8080")
|
|
log.Printf("Server starting on port %s", port)
|
|
log.Fatal(http.ListenAndServe(":"+port, nil))
|
|
}
|
|
|
|
func helloHandler(w http.ResponseWriter, r *http.Request) {
|
|
dbStatus := "disconnected"
|
|
|
|
if db != nil {
|
|
err := db.Ping()
|
|
if err == nil {
|
|
dbStatus = "connected"
|
|
}
|
|
}
|
|
|
|
response := Response{
|
|
Message: "Hello World! - Go + PostgreSQL + Next.js",
|
|
DBStatus: dbStatus,
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(response)
|
|
}
|
|
|
|
func healthHandler(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
|
|
}
|
|
|
|
func corsMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
|
|
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
|
|
|
|
if r.Method == "OPTIONS" {
|
|
w.WriteHeader(http.StatusOK)
|
|
return
|
|
}
|
|
|
|
next(w, r)
|
|
}
|
|
}
|
|
|
|
func getEnv(key, defaultValue string) string {
|
|
if value := os.Getenv(key); value != "" {
|
|
return value
|
|
}
|
|
return defaultValue
|
|
}
|