HTTP response streaming¶
Return a reader and send its content through the native Go Lambda streaming adapter. Deploy through a Lambda integration that supports response streaming.
Install¶
Use Go 1.27 or newer:
CGO_ENABLED=0 go get github.com/rambow-cloud/powertools-lambda-go/eventhandler/http@v1.2.0
CGO_ENABLED=0 go get github.com/rambow-cloud/powertools-lambda-go/logger@v1.2.0
CGO_ENABLED=0 go get github.com/aws/aws-lambda-go@v1.55.0
Return a server-sent event¶
This complete main.go includes the Lambda entry point, imports and setup error
logging. httpapi is the Powertools router; http is the standard net/http
package used for response headers.
Input
Code
package main
import (
"context"
"encoding/json"
"io"
"net/http"
"os"
"strings"
"github.com/aws/aws-lambda-go/lambda"
httpapi "github.com/rambow-cloud/powertools-lambda-go/eventhandler/http"
"github.com/rambow-cloud/powertools-lambda-go/logger"
)
func main() {
appLog := logger.New(logger.WithServiceName("streaming-orders"))
if err := runStream(); err != nil {
if logErr := appLog.Error("Application failed", err); logErr != nil {
panic(logErr)
}
os.Exit(1)
}
}
func runStream() error {
app := httpapi.New(httpapi.Options{})
if err := app.Get("/events", func(request *httpapi.RequestContext) (any, error) {
return httpapi.Response{
StatusCode: 200,
Headers: http.Header{"Content-Type": []string{"text/event-stream"}},
Body: strings.NewReader("data: ready\n\n"),
}, nil
}); err != nil {
return err
}
lambda.Start(httpapi.Streamify(func(ctx context.Context, event json.RawMessage, writer io.Writer) error {
return app.ResolveStream(ctx, event, writer)
}))
return nil
}
The callback uses the Lambda SDK's encoding/json.RawMessage type.
Output
This shows the HTTP client's body, without the custom runtime's integration framing. Replace the string reader with a context-aware producer for multiple incremental events.
Add observability¶
Place Logger/Tracer wrappers around the synchronous ResolveStream callback inside Streamify, so cleanup happens after body transfer. Disable response capture for a live reader.
See the complete streaming application for composition.
Things to know¶
ResolveStreamcloses the owned response body; the destination writer stays caller-owned.- Readers must honor cancellation or have a
Closethat interrupts a blocked read. - An error after response output starts cannot replace the response with a new status/body.
- A buffered console invocation does not demonstrate incremental client delivery. See AWS's supported streaming invocation paths.