feat: HTTP API server with SSE and SPA serving (HAN-389)
CI / test (pull_request) Failing after 1m21s

- web/api/server.go: HTTP server with CORS middleware, graceful shutdown,
  configurable listen address via NewServer(addr); uses net.Listen so the
  bound port is available via Addr() for tests.

- web/api/handler.go: REST handlers over Go 1.22 mux patterns:
    POST /api/traverse        start async traversal -> {id, status}
    GET  /api/traverse/{id}   poll status + results
    GET  /api/traverse/{id}/stream  SSE live progress events
    GET  /api/health          health check
  In-memory job store with 1-hour TTL and background cleanup goroutine.
  Background traversal via traverse.Traverser with hook-driven progress
  events fanned out to SSE subscribers.

- web/api/static/index.html: placeholder SPA shell (embedded via
  //go:embed static). Unknown URL paths fall back to index.html for
  client-side routing.

- cmd/server/main.go: runnable server binary with -addr flag and
  SIGINT/SIGTERM graceful shutdown.

All tests pass: go test -race ./...  |  go vet ./...

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
Gary Hansen
2026-06-08 04:19:02 +10:00
co-authored by Copilot multica-agent
parent bb3e9d3e36
commit 196eaa4a7a
5 changed files with 936 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
// Command server starts the ExploreDNS HTTP API server.
package main
import (
"flag"
"fmt"
"log"
"os"
"os/signal"
"syscall"
"time"
"github.com/hits/ExploreDNS/web/api"
)
func main() {
addr := flag.String("addr", ":8080", "listen address (host:port)")
flag.Parse()
srv := api.NewServer(*addr)
if err := srv.Start(); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
log.Printf("ExploreDNS API server listening on %s", srv.Addr())
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutting down...")
if err := srv.Shutdown(15 * time.Second); err != nil {
log.Printf("Shutdown error: %v", err)
}
}