package main import ( "context" "io" "log" "net/http" "os" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" ) var db *pgxpool.Pool func getUrlHandler(w http.ResponseWriter, req *http.Request) { var url string err := db.QueryRow(context.Background(), "select url from shortened_urls where id=$1", req.URL.Path).Scan(&url) switch err { case nil: http.Redirect(w, req, url, http.StatusSeeOther) case pgx.ErrNoRows: http.NotFound(w, req) default: http.Error(w, "Internal server error", http.StatusInternalServerError) } } func putUrlHandler(w http.ResponseWriter, req *http.Request) { id := req.URL.Path var url string if body, err := io.ReadAll(req.Body); err == nil { url = string(body) } else { http.Error(w, "Internal server error", http.StatusInternalServerError) return } if _, err := db.Exec(context.Background(), `insert into shortened_urls(id, url) values ($1, $2) on conflict (id) do update set url=excluded.url`, id, url); err == nil { w.WriteHeader(http.StatusOK) } else { http.Error(w, "Internal server error", http.StatusInternalServerError) } } func deleteUrlHandler(w http.ResponseWriter, req *http.Request) { if _, err := db.Exec(context.Background(), "delete from shortened_urls where id=$1", req.URL.Path); err == nil { w.WriteHeader(http.StatusOK) } else { http.Error(w, "Internal server error", http.StatusInternalServerError) } } func urlHandler(w http.ResponseWriter, req *http.Request) { switch req.Method { case "GET": getUrlHandler(w, req) case "PUT": putUrlHandler(w, req) case "DELETE": deleteUrlHandler(w, req) default: w.Header().Add("Allow", "GET, PUT, DELETE") w.WriteHeader(http.StatusMethodNotAllowed) } } func main() { poolConfig, err := pgxpool.ParseConfig(os.Getenv("DATABASE_URL")) if err != nil { log.Fatalln("Unable to parse DATABASE_URL:", err) } db, err = pgxpool.NewWithConfig(context.Background(), poolConfig) if err != nil { log.Fatalln("Unable to create connection pool:", err) } http.HandleFunc("/", urlHandler) log.Println("Starting URL shortener on localhost:8080") err = http.ListenAndServe("localhost:8080", nil) if err != nil { log.Fatalln("Unable to start web server:", err) } }