package httpapi import ( "context" "net/http" "gitea.maximumdirect.net/ejr/feedapi/bind" "gitea.maximumdirect.net/ejr/feedapi/endpoint" "gitea.maximumdirect.net/ejr/feedapi/render" "gitea.maximumdirect.net/ejr/feedapi/response" "gitea.maximumdirect.net/ejr/weatherfeeder/model" ) // Service describes the weather use-cases needed by the HTTP adapter. type Service interface { LatestObservation(ctx context.Context) (*model.WeatherObservation, error) LatestHourlyForecast(ctx context.Context) (*model.WeatherForecastRun, error) LatestActiveAlerts(ctx context.Context) (*model.WeatherAlertRun, error) } type emptyRequest struct{} func Definitions(svc Service) []endpoint.Definition { return []endpoint.Definition{ endpoint.GET( "/observations", bindFormatOnly, func(ctx context.Context, _ emptyRequest) (any, error) { obs, err := svc.LatestObservation(ctx) if err != nil { return nil, err } return response.Envelope{Data: obs}, nil }, endpoint.WithProduces(render.FormatJSON, render.FormatXML, render.FormatText), endpoint.WithTemplate("observations.txt.tmpl"), ), endpoint.GET( "/forecast/hourly", bindFormatOnly, func(ctx context.Context, _ emptyRequest) (any, error) { run, err := svc.LatestHourlyForecast(ctx) if err != nil { return nil, err } return response.Envelope{Data: run}, nil }, endpoint.WithProduces(render.FormatJSON, render.FormatXML, render.FormatText), endpoint.WithTemplate("forecast_hourly.txt.tmpl"), ), endpoint.GET( "/alerts/active", bindFormatOnly, func(ctx context.Context, _ emptyRequest) (any, error) { run, err := svc.LatestActiveAlerts(ctx) if err != nil { return nil, err } return response.Envelope{Data: run}, nil }, endpoint.WithProduces(render.FormatJSON, render.FormatXML, render.FormatText), endpoint.WithTemplate("alerts_active.txt.tmpl"), ), } } func bindFormatOnly(r *http.Request) (emptyRequest, error) { _, err := bind.CommonQueryParams(r, bind.QueryPolicy{ AllowFormat: true, RejectUnknown: true, }) if err != nil { return emptyRequest{}, err } return emptyRequest{}, nil }