---
name: http_serve
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func HTTPServe(addr string, handler http.Handler, ctx context.Context) error"
description: "Arranca un servidor HTTP en addr y realiza graceful shutdown cuando ctx se cancela. Espera hasta 30 segundos para que las conexiones activas cierren."
tags: [http, server, serve, graceful, shutdown, context, infra]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [context, fmt, net/http, time]
params:
  - name: addr
    desc: "direccion donde escuchar (ej: \":8080\", \"0.0.0.0:9090\")"
  - name: handler
    desc: "http.Handler que procesa las peticiones (normalmente un *http.ServeMux con middlewares)"
  - name: ctx
    desc: "contexto que al cancelarse dispara el graceful shutdown del servidor"
output: "nil si el servidor se detuvo correctamente por cancelacion de contexto, error si fallo al arrancar o al hacer shutdown"
tested: true
tests: ["servidor arranca y responde peticiones", "graceful shutdown al cancelar contexto"]
test_file_path: "functions/infra/http_server_test.go"
file_path: "functions/infra/http_serve.go"
---

## Ejemplo

```go
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer cancel()

mux := HTTPRouter(routes)
chain := HTTPMiddlewareChain(HTTPLoggerMiddleware(os.Stderr))
if err := HTTPServe(":8080", chain(mux), ctx); err != nil {
    log.Fatal(err)
}
```

## Notas

Arranca ListenAndServe en una goroutine y espera en un select: si el servidor falla devuelve el error inmediatamente, si ctx se cancela hace Shutdown con timeout de 30s. El patron estandar es usar signal.NotifyContext con SIGINT/SIGTERM para el graceful shutdown.
