Documentation
¶
Overview ¶
Package nws provides an unofficial client for the National Weather Service API.
Create a Client with NewClient and call its resource services. Reuse the client across requests; it is safe for concurrent use.
Resource methods return a typed result, a Response, and an error. Results are nil on error. Client.Get documents which errors return a response.
See https://www.weather.gov/documentation/services-web-api for API guidance.
Index ¶
- type ActiveAlertCounts
- type Alert
- type AlertCollection
- type AlertEventTypes
- type AlertGeocode
- type AlertReference
- type AlertsService
- func (s *AlertsService) CountActive(ctx context.Context) (*ActiveAlertCounts, *Response, error)
- func (s *AlertsService) Get(ctx context.Context, id string) (*Feature[Alert], *Response, error)
- func (s *AlertsService) List(ctx context.Context, query url.Values) (*AlertCollection, *Response, error)
- func (s *AlertsService) ListActive(ctx context.Context, query url.Values) (*AlertCollection, *Response, error)
- func (s *AlertsService) ListTypes(ctx context.Context) (*AlertEventTypes, *Response, error)
- type AstronomicalData
- type Client
- type CloudLayer
- type Feature
- type FeatureCollection
- type Gridpoint
- type GridpointForecast
- type GridpointForecastPeriod
- type GridpointHazard
- type GridpointIntervalValue
- type GridpointLayer
- type GridpointWeather
- type GridpointsService
- type MetarPhenomenon
- type Observation
- type ObservationCollection
- type Option
- type PaginationInfo
- type Point
- type PointsService
- type ProblemDetail
- type QuantitativeValue
- type RelativeLocation
- type RequestError
- type Response
- type RetryPolicy
- type Station
- type StationCollection
- type StationsService
- func (s *StationsService) Get(ctx context.Context, id string) (*Feature[Station], *Response, error)
- func (s *StationsService) GetLatestObservation(ctx context.Context, stationID string, query url.Values) (*Feature[Observation], *Response, error)
- func (s *StationsService) GetObservation(ctx context.Context, stationID, timestamp string) (*Feature[Observation], *Response, error)
- func (s *StationsService) List(ctx context.Context, resource string, query url.Values) (*StationCollection, *Response, error)
- func (s *StationsService) ListObservations(ctx context.Context, stationID string, query url.Values) (*ObservationCollection, *Response, error)
- type WeatherRadio
- type Zone
- type ZoneForecast
- type ZoneForecastPeriod
- type ZonesService
- func (s *ZonesService) Get(ctx context.Context, zoneType, id string) (*Feature[Zone], *Response, error)
- func (s *ZonesService) GetForecast(ctx context.Context, zoneType, id string) (*Feature[ZoneForecast], *Response, error)
- func (s *ZonesService) List(ctx context.Context, query url.Values) (*FeatureCollection[Zone], *Response, error)
- func (s *ZonesService) ListByType(ctx context.Context, zoneType string, query url.Values) (*FeatureCollection[Zone], *Response, error)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ActiveAlertCounts ¶
type ActiveAlertCounts struct {
Total int `json:"total"`
Land int `json:"land"`
Marine int `json:"marine"`
Regions map[string]int `json:"regions"`
Areas map[string]int `json:"areas"`
Zones map[string]int `json:"zones"`
}
ActiveAlertCounts models the inline success-response schema for GET /alerts/active/count, grouping active alerts by land/marine coverage and NWS codes. Missing map keys mean NWS supplied no count for that code.
type Alert ¶
type Alert struct {
ID string `json:"id"`
AreaDesc string `json:"areaDesc"`
Geocode *AlertGeocode `json:"geocode"`
AffectedZones []string `json:"affectedZones"`
References []AlertReference `json:"references"`
Sent string `json:"sent"`
Effective string `json:"effective"`
Onset *string `json:"onset"`
Expires string `json:"expires"`
Ends *string `json:"ends"`
Status string `json:"status"`
MessageType string `json:"messageType"`
Category string `json:"category"`
Severity string `json:"severity"`
Certainty string `json:"certainty"`
Urgency string `json:"urgency"`
Event string `json:"event"`
Sender string `json:"sender"`
SenderName string `json:"senderName"`
Headline *string `json:"headline"`
Description string `json:"description"`
Instruction *string `json:"instruction"`
Note *string `json:"note"`
Response string `json:"response"`
Parameters map[string][]json.RawMessage `json:"parameters"`
Scope string `json:"scope"`
Code string `json:"code"`
Language string `json:"language"`
Web string `json:"web"`
EventCode map[string][]json.RawMessage `json:"eventCode"`
}
Alert models the NWS OpenAPI Alert schema used as AlertGeoJson.properties. It keeps NWS CAP-derived fields, with enums and timestamps left as strings.
Schema: https://api.weather.gov/openapi.json#/components/schemas/Alert
type AlertCollection ¶
type AlertCollection struct {
FeatureCollection[Alert]
Title string `json:"title,omitempty"`
Updated string `json:"updated,omitempty"`
Pagination *PaginationInfo `json:"pagination,omitempty"`
}
AlertCollection models the NWS OpenAPI AlertCollectionGeoJson and ActiveAlertCollectionGeoJson schemas. Pagination is optional, belongs to AlertCollectionGeoJson, and is not followed automatically.
Schemas: https://api.weather.gov/openapi.json#/components/schemas/AlertCollectionGeoJson https://api.weather.gov/openapi.json#/components/schemas/ActiveAlertCollectionGeoJson
type AlertEventTypes ¶
type AlertEventTypes struct {
Types []string `json:"eventTypes"`
}
AlertEventTypes models the inline success-response schema for GET /alerts/types, containing NWS's recognized alert event names.
type AlertGeocode ¶
AlertGeocode models the inline geocode object in the NWS OpenAPI Alert schema, listing NWS public zone/county identifiers and SAME codes.
Schema: https://api.weather.gov/openapi.json#/components/schemas/Alert/properties/geocode
type AlertReference ¶
type AlertReference struct {
ID string `json:"@id"`
Identifier string `json:"identifier"`
Sender string `json:"sender"`
Sent string `json:"sent"`
}
AlertReference models an inline references entry in the NWS OpenAPI Alert schema, identifying a prior alert that this alert updates or replaces.
Schema: https://api.weather.gov/openapi.json#/components/schemas/Alert/properties/references/items
type AlertsService ¶
type AlertsService struct {
// contains filtered or unexported fields
}
AlertsService provides access to NWS alerts endpoints. Use the corresponding field on a Client constructed with NewClient.
func (*AlertsService) CountActive ¶
func (s *AlertsService) CountActive(ctx context.Context) (*ActiveAlertCounts, *Response, error)
CountActive returns the API's unfiltered active-alert counts.
func (*AlertsService) List ¶
func (s *AlertsService) List(ctx context.Context, query url.Values) (*AlertCollection, *Response, error)
List returns one page of alerts with NWS query parameters (including cursor). Follow AlertCollection.Pagination.Next with Client.Get into an AlertCollection.
Example ¶
package main
import (
"context"
"fmt"
"io"
"net/http"
"net/http/httptest"
"net/url"
"time"
nws "github.com/Three-Ships/national-weather-service-client"
)
func main() {
// A local server supplies two pages so the example does not contact NWS.
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.RequestURI() {
case "/alerts?area=DC&status=actual":
io.WriteString(w, `{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"event":"Winter Weather Advisory"}}],"pagination":{"next":"/alerts?area=DC&cursor=next&status=actual"}}`)
case "/alerts?area=DC&cursor=next&status=actual":
io.WriteString(w, `{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"event":"Wind Advisory"}}]}`)
default:
http.Error(w, "unexpected request: "+r.URL.String(), http.StatusBadRequest)
}
}))
defer server.Close()
client, err := nws.NewClient("example-reader/1.0 (weather@example.com)",
nws.WithRequestInterval(0), nws.WithBaseURL(server.URL))
if err != nil {
panic(err)
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
page, _, err := client.Alerts.List(ctx, url.Values{"area": {"DC"}, "status": {"actual"}})
if err != nil {
panic(err)
}
for {
for _, feature := range page.Features {
fmt.Println(feature.Properties.Event)
}
if page.Pagination == nil || page.Pagination.Next == "" {
break
}
// Next contains the continuation query; do not reapply initial filters.
// Decode into a fresh collection so omitted metadata cannot remain stale.
var next nws.AlertCollection
if _, err := client.Get(ctx, page.Pagination.Next, nil, &next); err != nil {
panic(err)
}
page = &next
}
}
Output: Winter Weather Advisory Wind Advisory
func (*AlertsService) ListActive ¶
func (s *AlertsService) ListActive(ctx context.Context, query url.Values) (*AlertCollection, *Response, error)
ListActive returns currently active alerts with caller-selected filters. No status filter is imposed; pass status=actual to exclude exercises/tests.
func (*AlertsService) ListTypes ¶
func (s *AlertsService) ListTypes(ctx context.Context) (*AlertEventTypes, *Response, error)
ListTypes returns recognized event names without treating the list as a fixed enum enforced by the client.
type AstronomicalData ¶
type AstronomicalData struct {
Sunrise *string `json:"sunrise"`
Sunset *string `json:"sunset"`
Transit *string `json:"transit"`
CivilTwilightBegin *string `json:"civilTwilightBegin"`
CivilTwilightEnd *string `json:"civilTwilightEnd"`
NauticalTwilightBegin *string `json:"nauticalTwilightBegin"`
NauticalTwilightEnd *string `json:"nauticalTwilightEnd"`
AstronomicalTwilightBegin *string `json:"astronomicalTwilightBegin"`
AstronomicalTwilightEnd *string `json:"astronomicalTwilightEnd"`
}
AstronomicalData models the NWS OpenAPI AstronomicalData schema, keeping event times as RFC3339 strings. Events may be null during polar day or night. The client neither calculates times nor converts time zones.
Schema: https://api.weather.gov/openapi.json#/components/schemas/AstronomicalData
type Client ¶
type Client struct {
Points *PointsService
Gridpoints *GridpointsService
Alerts *AlertsService
Stations *StationsService
Zones *ZonesService
// contains filtered or unexported fields
}
Client is safe for concurrent requests when constructed with NewClient. Reuse an instance to share connection pooling and pacing; do not copy it after use. Resource services share this client's HTTP policy. Do not replace service fields while the client is in use.
func NewClient ¶
NewClient validates request configuration before any requests. userAgent should identify the application and include contact details, for example "weather-reader/1.0 (weather@example.com)". Empty values and control characters are rejected. The default HTTP timeout is 30s per attempt; WithHTTPClient replaces it. Set a context deadline to also bound pacing and retry waits.
func (*Client) Fetch ¶
func (c *Client) Fetch(ctx context.Context, resource string, query url.Values, accept string) (*Response, error)
Fetch retrieves a buffered response, including non-JSON representations. resource may be an API-relative path or a discovered same-origin URL; both must stay inside any configured path prefix. query replaces matching parameters and retains the rest. Malformed URL query encoding fails before HTTP rather than dropping filters; parameter names and values are otherwise passed through to NWS. An empty accept selects application/geo+json.
Each attempt follows at most three same-origin redirects within the base path. Attempts count Do calls, not redirect hops. Retries cover transport failures, incomplete successful-response reads, 429, and 5xx. Other HTTP statuses are terminal. Retry-After accepts delta-seconds and HTTP dates. On failure, Fetch returns a nil response; request failures are reported as RequestError.
func (*Client) Get ¶
func (c *Client) Get(ctx context.Context, resource string, query url.Values, dst any) (*Response, error)
Get fetches JSON using Fetch's request policy and decodes it into dst, which must be a non-nil pointer. GeoJSON and JSON are preferred over JSON-LD so resource packages receive feature envelopes when the endpoint offers them. Use json.RawMessage or a caller-defined struct for unmodeled fields.
Get returns the buffered Response after a successful fetch, including when decoding fails. Fetch failures return a nil response. Decoding errors, including invalid destination types, return a non-retryable RequestError; dst may be partially populated and must not be used after a decoding error.
Example ¶
client, err := NewClient("example-reader/1.0 (weather@example.com)",
WithHTTPClient(&http.Client{Transport: roundTripFunc(func(r *http.Request) (*http.Response, error) {
return testResponse([]byte(`{"glossary":[{"term":"Dew Point","definition":"A temperature."}]}`)), nil
})}))
if err != nil {
panic(err)
}
var result struct {
Glossary []struct{ Term, Definition string }
}
if _, err := client.Get(context.Background(), "/glossary", nil, &result); err != nil {
panic(err)
}
fmt.Println(result.Glossary[0].Term)
Output: Dew Point
type CloudLayer ¶
type CloudLayer struct {
Base QuantitativeValue `json:"base"`
Amount string `json:"amount"`
}
CloudLayer models an inline cloudLayers entry in the NWS OpenAPI Observation schema, keeping NWS base-height units and the METAR sky-coverage code.
Schema: https://api.weather.gov/openapi.json#/components/schemas/Observation/properties/cloudLayers/items
type Feature ¶
type Feature[T any] struct { Context json.RawMessage `json:"@context,omitempty"` ID string `json:"id,omitempty"` Type string `json:"type"` Geometry json.RawMessage `json:"geometry"` Properties T `json:"properties"` }
Feature models the NWS OpenAPI GeoJsonFeature schema with properties of type T. Geometry and Context retain their source representation because NWS serves multiple geometry and JSON-LD context shapes.
Schema: https://api.weather.gov/openapi.json#/components/schemas/GeoJsonFeature
type FeatureCollection ¶
type FeatureCollection[T any] struct { Context json.RawMessage `json:"@context,omitempty"` Type string `json:"type"` Features []Feature[T] `json:"features"` }
FeatureCollection models one page of the NWS OpenAPI GeoJsonFeatureCollection schema. Resource packages add collection-specific metadata, such as alert timestamps and station pagination.
Schema: https://api.weather.gov/openapi.json#/components/schemas/GeoJsonFeatureCollection
type Gridpoint ¶
type Gridpoint struct {
ID string `json:"@id,omitempty"`
Type string `json:"@type,omitempty"`
Context json.RawMessage `json:"@context,omitempty"`
Geometry string `json:"geometry,omitempty"`
UpdateTime string `json:"updateTime"`
ValidTimes string `json:"validTimes"`
Elevation QuantitativeValue `json:"elevation"`
ForecastOffice string `json:"forecastOffice"`
GridID string `json:"gridId"`
GridX int `json:"gridX"`
GridY int `json:"gridY"`
Weather *GridpointLayer[[]GridpointWeather] `json:"weather,omitempty"`
Hazards *GridpointLayer[[]GridpointHazard] `json:"hazards,omitempty"`
Layers map[string]GridpointLayer[*float64] `json:"-"`
}
Gridpoint models the NWS OpenAPI Gridpoint schema used as GridpointGeoJson.properties. Numeric Layers are keyed by source names such as "temperature", "skyCover", and "quantitativePrecipitation". The schema makes these additional properties, so new numeric layers are retained without adding fields. Layers are stored in a map here but remain top-level properties in JSON. Missing layers remain absent; null values remain nil. Weather and Hazards have distinct categorical schemas.
Schema: https://api.weather.gov/openapi.json#/components/schemas/Gridpoint
func (Gridpoint) MarshalJSON ¶
MarshalJSON emits Layers as top-level properties to match the NWS JSON format. Layer names that conflict with metadata or categorical fields are errors.
func (*Gridpoint) UnmarshalJSON ¶
UnmarshalJSON rejects additional properties that cannot be decoded as numeric layers.
type GridpointForecast ¶
type GridpointForecast struct {
Units string `json:"units"`
ForecastGenerator string `json:"forecastGenerator"`
GeneratedAt string `json:"generatedAt"`
UpdateTime string `json:"updateTime"`
ValidTimes string `json:"validTimes"`
Elevation QuantitativeValue `json:"elevation"`
Periods []GridpointForecastPeriod `json:"periods"`
}
GridpointForecast models the shared properties of the NWS OpenAPI Gridpoint12hForecast and GridpointHourlyForecast schemas. Feature[GridpointForecast] supplies the GeoJSON envelope for Gridpoint12hForecastGeoJson or GridpointHourlyForecastGeoJson.
Schemas: https://api.weather.gov/openapi.json#/components/schemas/Gridpoint12hForecast https://api.weather.gov/openapi.json#/components/schemas/GridpointHourlyForecast
type GridpointForecastPeriod ¶
type GridpointForecastPeriod struct {
Number int `json:"number"`
Name string `json:"name"`
StartTime string `json:"startTime"`
EndTime string `json:"endTime"`
IsDaytime bool `json:"isDaytime"`
Temperature json.RawMessage `json:"temperature"`
TemperatureUnit string `json:"temperatureUnit,omitempty"`
TemperatureTrend *string `json:"temperatureTrend"`
ProbabilityOfPrecipitation QuantitativeValue `json:"probabilityOfPrecipitation"`
Dewpoint *QuantitativeValue `json:"dewpoint,omitempty"`
RelativeHumidity *QuantitativeValue `json:"relativeHumidity,omitempty"`
WindSpeed json.RawMessage `json:"windSpeed"`
WindGust json.RawMessage `json:"windGust,omitempty"`
WindDirection string `json:"windDirection"`
Icon string `json:"icon"`
ShortForecast string `json:"shortForecast"`
DetailedForecast string `json:"detailedForecast"`
}
GridpointForecastPeriod combines the NWS OpenAPI Gridpoint12hForecastPeriod and GridpointHourlyForecastPeriod schemas. Dewpoint and RelativeHumidity are hourly-only fields. It uses raw JSON for fields whose format depends on NWS feature flags: Temperature is an integer or QuantitativeValue; WindSpeed is a string or QuantitativeValue; WindGust also permits null. Keeping these fields raw leaves callers free to choose a format without converting values or units.
Schemas: https://api.weather.gov/openapi.json#/components/schemas/Gridpoint12hForecastPeriod https://api.weather.gov/openapi.json#/components/schemas/GridpointHourlyForecastPeriod
Example ¶
package main
import (
"encoding/json"
"fmt"
nws "github.com/Three-Ships/national-weather-service-client"
)
func main() {
// Display both NWS formats without converting their values or units.
formatValue := func(raw json.RawMessage, scalarUnit string) string {
var value any
if err := json.Unmarshal(raw, &value); err != nil {
panic(err)
}
switch value := value.(type) {
case nil:
return "missing"
case float64:
return fmt.Sprintf("%g %s", value, scalarUnit)
case string:
return value
default:
var measurement nws.QuantitativeValue
if err := json.Unmarshal(raw, &measurement); err != nil {
panic(err)
}
if measurement.Value == nil {
return "missing"
}
return fmt.Sprintf("%g %s", *measurement.Value, measurement.UnitCode)
}
}
periods := []nws.GridpointForecastPeriod{
{
Temperature: json.RawMessage(`32`),
TemperatureUnit: "F",
WindSpeed: json.RawMessage(`"5 to 10 mph"`),
},
{
Temperature: json.RawMessage(`{"value":0,"unitCode":"wmoUnit:degC"}`),
WindSpeed: json.RawMessage(`{"value":null,"unitCode":"wmoUnit:km_h-1"}`),
},
}
for _, period := range periods {
fmt.Println(formatValue(period.Temperature, period.TemperatureUnit))
fmt.Println(formatValue(period.WindSpeed, ""))
}
}
Output: 32 F 5 to 10 mph 0 wmoUnit:degC missing
type GridpointHazard ¶
type GridpointHazard struct {
Phenomenon string `json:"phenomenon"`
Significance string `json:"significance"`
EventNumber *int `json:"event_number"`
}
GridpointHazard models an inline hazard value in the NWS OpenAPI Gridpoint schema, retaining source P-VTEC codes and a nullable event number.
type GridpointIntervalValue ¶
type GridpointIntervalValue[T any] struct { ValidTime string `json:"validTime"` Value T `json:"value"` }
GridpointIntervalValue generalizes validTime/value entries in NWS OpenAPI gridpoint layers. GridpointQuantitativeValueLayer entries use *float64 for T; weather and hazard entries use slices of their categorical values. ValidTime remains an ISO 8601 start/duration or start/end string. Callers decide how to expand or align the interval.
type GridpointLayer ¶
type GridpointLayer[T any] struct { UOM string `json:"uom,omitempty"` Values []GridpointIntervalValue[T] `json:"values"` }
GridpointLayer generalizes the NWS OpenAPI GridpointQuantitativeValueLayer schema and the inline weather/hazard layers in Gridpoint. Numeric layers use GridpointLayer[*float64]. Values retain source order; UOM may be absent for categorical layers.
Schema: https://api.weather.gov/openapi.json#/components/schemas/GridpointQuantitativeValueLayer
type GridpointWeather ¶
type GridpointWeather struct {
Coverage *string `json:"coverage"`
Weather *string `json:"weather"`
Intensity *string `json:"intensity"`
Visibility QuantitativeValue `json:"visibility"`
Attributes []string `json:"attributes"`
}
GridpointWeather models an inline weather value in the NWS OpenAPI Gridpoint schema, describing one expected weather phenomenon in a grid interval.
type GridpointsService ¶
type GridpointsService struct {
// contains filtered or unexported fields
}
GridpointsService provides access to NWS gridpoints endpoints. Use the corresponding field on a Client constructed with NewClient.
func (*GridpointsService) Get ¶
func (s *GridpointsService) Get(ctx context.Context, resource string) (*Feature[Gridpoint], *Response, error)
Get fetches a discovered forecastGridData URL (or API path).
func (*GridpointsService) GetForecast ¶
func (s *GridpointsService) GetForecast(ctx context.Context, resource string, query url.Values) (*Feature[GridpointForecast], *Response, error)
GetForecast fetches a forecast or forecastHourly link returned by PointsService.Get. query accepts NWS parameters such as units=si. Use a caller-owned transport for feature-flag headers, or Client.Get for caller-defined period types.
type MetarPhenomenon ¶
type MetarPhenomenon struct {
Intensity *string `json:"intensity"`
Modifier *string `json:"modifier"`
Weather string `json:"weather"`
RawString string `json:"rawString"`
InVicinity bool `json:"inVicinity"`
}
MetarPhenomenon models the NWS OpenAPI MetarPhenomenon schema, retaining decoded METAR codes and raw text. Intensity and Modifier may be null; enums remain strings so new NWS codes are not discarded.
Schema: https://api.weather.gov/openapi.json#/components/schemas/MetarPhenomenon
type Observation ¶
type Observation struct {
Context json.RawMessage `json:"@context,omitempty"`
Geometry string `json:"geometry,omitempty"`
ID string `json:"@id,omitempty"`
Type string `json:"@type,omitempty"`
Elevation QuantitativeValue `json:"elevation"`
Station string `json:"station"`
StationID string `json:"stationId"`
StationName string `json:"stationName"`
Timestamp string `json:"timestamp"`
RawMessage string `json:"rawMessage"`
TextDescription string `json:"textDescription"`
Icon *string `json:"icon"`
PresentWeather []MetarPhenomenon `json:"presentWeather"`
Temperature QuantitativeValue `json:"temperature"`
Dewpoint QuantitativeValue `json:"dewpoint"`
WindDirection QuantitativeValue `json:"windDirection"`
WindSpeed QuantitativeValue `json:"windSpeed"`
WindGust QuantitativeValue `json:"windGust"`
BarometricPressure QuantitativeValue `json:"barometricPressure"`
SeaLevelPressure QuantitativeValue `json:"seaLevelPressure"`
Visibility QuantitativeValue `json:"visibility"`
MaxTemperatureLast24Hours QuantitativeValue `json:"maxTemperatureLast24Hours"`
MinTemperatureLast24Hours QuantitativeValue `json:"minTemperatureLast24Hours"`
PrecipitationLastHour QuantitativeValue `json:"precipitationLastHour"`
PrecipitationLast3Hours QuantitativeValue `json:"precipitationLast3Hours"`
PrecipitationLast6Hours QuantitativeValue `json:"precipitationLast6Hours"`
RelativeHumidity QuantitativeValue `json:"relativeHumidity"`
WindChill QuantitativeValue `json:"windChill"`
HeatIndex QuantitativeValue `json:"heatIndex"`
CloudLayers []CloudLayer `json:"cloudLayers"`
}
Observation models the NWS OpenAPI Observation schema used as ObservationGeoJson.properties. It keeps NWS measurements, unit codes, quality-control flags, and timestamps unchanged. A measurement's nil Value means the reading is missing.
Schema: https://api.weather.gov/openapi.json#/components/schemas/Observation
type ObservationCollection ¶
type ObservationCollection struct {
FeatureCollection[Observation]
Pagination *PaginationInfo `json:"pagination,omitempty"`
}
ObservationCollection models one page of the NWS OpenAPI ObservationCollectionGeoJson schema. Pagination is optional and is not followed automatically.
Schema: https://api.weather.gov/openapi.json#/components/schemas/ObservationCollectionGeoJson
type Option ¶
type Option func(*Client)
Option configures a client. Repeated options replace earlier values.
func WithBaseURL ¶
WithBaseURL sets an absolute HTTP(S) API origin, optionally with a path prefix. Use an httptest server URL for local tests. Discovered links must remain on this origin and inside that prefix.
func WithHTTPClient ¶
WithHTTPClient uses client's transport, cookie jar, and timeout. Its redirect policy is replaced on a copy, leaving the supplied client's settings unchanged. Shared dependencies must be safe for concurrent use. The caller owns transport cleanup.
func WithRequestInterval ¶
WithRequestInterval sets the minimum spacing between HTTP attempt admissions, including retries and redirects. Zero disables pacing; the default is 200ms. It is not an in-flight limit or a quota shared between client instances.
func WithRetryPolicy ¶
func WithRetryPolicy(policy RetryPolicy) Option
WithRetryPolicy replaces the default four attempts, 1s initial delay, and 30s maximum delay. All fields must be positive, with MaxDelay >= InitialDelay.
type PaginationInfo ¶
type PaginationInfo struct {
Next string `json:"next"`
}
PaginationInfo models the NWS OpenAPI PaginationInfo schema. Its next-page URL can be passed to Client.Get.
Schema: https://api.weather.gov/openapi.json#/components/schemas/PaginationInfo
type Point ¶
type Point struct {
ID string `json:"@id,omitempty"`
Type string `json:"type"`
CWA string `json:"cwa"`
ForecastOffice string `json:"forecastOffice"`
GridID string `json:"gridId"`
GridX int `json:"gridX"`
GridY int `json:"gridY"`
Forecast string `json:"forecast"`
ForecastHourly string `json:"forecastHourly"`
ForecastGridData string `json:"forecastGridData"`
ObservationStations string `json:"observationStations"`
RelativeLocation *Feature[RelativeLocation] `json:"relativeLocation,omitempty"`
ForecastZone string `json:"forecastZone"`
County string `json:"county"`
FireWeatherZone string `json:"fireWeatherZone"`
TimeZone string `json:"timeZone"`
RadarStation string `json:"radarStation"`
AstronomicalData *AstronomicalData `json:"astronomicalData,omitempty"`
NWR *WeatherRadio `json:"nwr,omitempty"`
}
Point models the NWS OpenAPI Point schema used as PointGeoJson.properties. ForecastZone, County, FireWeatherZone, and ForecastOffice are URLs to fetch separately. AstronomicalData applies to the current day reported by NWS.
Schema: https://api.weather.gov/openapi.json#/components/schemas/Point
type PointsService ¶
type PointsService struct {
// contains filtered or unexported fields
}
PointsService provides access to NWS points endpoints. Use the corresponding field on a Client constructed with NewClient.
func (*PointsService) Get ¶
func (s *PointsService) Get(ctx context.Context, latitude, longitude float64) (*Feature[Point], *Response, error)
Get resolves a coordinate to NWS metadata and resource links. Coordinates are rounded to four decimal places as expected by NWS. Non-finite or out-of-range inputs fail before any HTTP request; linked resources require separate calls.
Example ¶
package main
import (
"context"
"fmt"
"io"
"net/http"
"net/http/httptest"
nws "github.com/Three-Ships/national-weather-service-client"
)
func main() {
// A local server keeps this example independent of live weather data.
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "public, max-age=300")
io.WriteString(w, `{"type":"Feature","properties":{"gridId":"LWX","timeZone":"America/New_York","forecastGridData":"https://api.weather.gov/gridpoints/LWX/97,71"}}`)
}))
defer server.Close()
client, err := nws.NewClient("example-reader/1.0 (weather@example.com)", nws.WithBaseURL(server.URL))
if err != nil {
panic(err)
}
point, response, err := client.Points.Get(context.Background(), 38.8977, -77.0365)
if err != nil {
panic(err)
}
fmt.Println(response.Header.Get("Cache-Control"))
fmt.Println(point.Properties.TimeZone)
fmt.Println(point.Properties.ForecastGridData)
}
Output: public, max-age=300 America/New_York https://api.weather.gov/gridpoints/LWX/97,71
type ProblemDetail ¶
type ProblemDetail struct {
Type string `json:"type"`
Title string `json:"title"`
Status int `json:"status"`
Detail string `json:"detail"`
Instance string `json:"instance"`
CorrelationID string `json:"correlationId"`
}
ProblemDetail models the NWS OpenAPI ProblemDetail schema, an RFC 7807 error document. Its Status may differ from the actual HTTP status; use RequestError.StatusCode for retry decisions.
Schema: https://api.weather.gov/openapi.json#/components/schemas/ProblemDetail
type QuantitativeValue ¶
type QuantitativeValue struct {
Value *float64 `json:"value"`
MaxValue *float64 `json:"maxValue,omitempty"`
MinValue *float64 `json:"minValue,omitempty"`
UnitCode string `json:"unitCode"`
QualityControl string `json:"qualityControl,omitempty"`
}
QuantitativeValue models the NWS OpenAPI QuantitativeValue measurement schema. It keeps NWS units and optional bounds. A nil Value means missing data; a non-nil pointer to zero is a real measurement. MinValue and MaxValue come from NWS and are never calculated here.
Schema: https://api.weather.gov/openapi.json#/components/schemas/QuantitativeValue
type RelativeLocation ¶
type RelativeLocation struct {
City string `json:"city"`
State string `json:"state"`
Distance QuantitativeValue `json:"distance"`
Bearing QuantitativeValue `json:"bearing"`
}
RelativeLocation models the NWS OpenAPI RelativeLocation schema used as RelativeLocationGeoJson.properties. It describes a nearby named location.
Schema: https://api.weather.gov/openapi.json#/components/schemas/RelativeLocation
type RequestError ¶
type RequestError struct {
URL string
Attempts int
StatusCode int
Retryable bool
Problem ProblemDetail
Body string
Err error
}
RequestError reports a failure after the client has applied its retry policy. Inspect it with errors.As; errors.Is can inspect the wrapped cause. Retryable describes the cause, not whether attempts remain. Attempts counts http.Client.Do calls, not redirect hops. StatusCode is zero when no HTTP status is available. Body contains at most 64 KiB of an HTTP error response.
func (*RequestError) Error ¶
func (e *RequestError) Error() string
func (*RequestError) Unwrap ¶
func (e *RequestError) Unwrap() error
Unwrap preserves transport, decoding, and context error identity.
type Response ¶
type Response struct {
URL string
StatusCode int
Header http.Header
Body []byte
// contains filtered or unexported fields
}
Response contains the unmodified source body and final response headers. Successful bodies are buffered in full; there is nothing to close.
type RetryPolicy ¶
RetryPolicy bounds total HTTP attempts, including the initial request. InitialDelay and MaxDelay bound exponential full-jitter backoff. Retry-After is a minimum wait and may exceed MaxDelay; the caller's context still wins.
type Station ¶
type Station struct {
ID string `json:"@id,omitempty"`
Elevation QuantitativeValue `json:"elevation"`
StationIdentifier string `json:"stationIdentifier"`
Name string `json:"name"`
TimeZone string `json:"timeZone"`
Provider string `json:"provider"`
SubProvider string `json:"subProvider"`
Forecast string `json:"forecast"`
County string `json:"county"`
FireWeatherZone string `json:"fireWeatherZone"`
Distance *QuantitativeValue `json:"distance,omitempty"`
Bearing *QuantitativeValue `json:"bearing,omitempty"`
}
Station models the NWS OpenAPI ObservationStation schema used as ObservationStationGeoJson.properties, containing observation-station metadata.
Schema: https://api.weather.gov/openapi.json#/components/schemas/ObservationStation
type StationCollection ¶
type StationCollection struct {
FeatureCollection[Station]
Pagination *PaginationInfo `json:"pagination,omitempty"`
ObservationStations []string `json:"observationStations,omitempty"`
}
StationCollection models one page of the NWS OpenAPI ObservationStationCollectionGeoJson schema. ObservationStations retains source station URLs when present; Pagination is not followed automatically.
Schema: https://api.weather.gov/openapi.json#/components/schemas/ObservationStationCollectionGeoJson
type StationsService ¶
type StationsService struct {
// contains filtered or unexported fields
}
StationsService provides access to NWS stations endpoints. Use the corresponding field on a Client constructed with NewClient.
func (*StationsService) GetLatestObservation ¶
func (s *StationsService) GetLatestObservation(ctx context.Context, stationID string, query url.Values) (*Feature[Observation], *Response, error)
GetLatestObservation accepts the NWS require_qc query parameter. It does not impose a quality-control requirement on callers.
func (*StationsService) GetObservation ¶
func (s *StationsService) GetObservation(ctx context.Context, stationID, timestamp string) (*Feature[Observation], *Response, error)
GetObservation requires an RFC3339 timestamp. Its original offset and precision are retained in the request; invalid timestamps fail before HTTP.
func (*StationsService) List ¶
func (s *StationsService) List(ctx context.Context, resource string, query url.Values) (*StationCollection, *Response, error)
List fetches one station collection page. Resource may be "stations" or a discovered observationStations link; query accepts the endpoint's filters.
func (*StationsService) ListObservations ¶
func (s *StationsService) ListObservations(ctx context.Context, stationID string, query url.Values) (*ObservationCollection, *Response, error)
ListObservations returns station history with NWS query parameters such as start, end, limit, and cursor. No time window or quality filter is imposed.
type WeatherRadio ¶
type WeatherRadio struct {
Transmitter *string `json:"transmitter"`
SAMECode string `json:"sameCode"`
AreaBroadcast *string `json:"areaBroadcast"`
PointBroadcast *string `json:"pointBroadcast"`
}
WeatherRadio models the inline nwr object in the NWS OpenAPI Point schema, containing NOAA Weather Radio discovery metadata.
Schema: https://api.weather.gov/openapi.json#/components/schemas/Point/properties/nwr
type Zone ¶
type Zone struct {
ID string `json:"id"`
Type string `json:"type"`
Name string `json:"name"`
EffectiveDate string `json:"effectiveDate"`
ExpirationDate string `json:"expirationDate"`
State *string `json:"state"`
ForecastOffice string `json:"forecastOffice"`
GridIdentifier string `json:"gridIdentifier"`
AWIPSLocationIdentifier string `json:"awipsLocationIdentifier"`
CWA []string `json:"cwa"`
ForecastOffices []string `json:"forecastOffices"`
TimeZone []string `json:"timeZone"`
ObservationStations []string `json:"observationStations"`
RadarStation *string `json:"radarStation"`
}
Zone models the NWS OpenAPI Zone schema used as ZoneGeoJson.properties. It describes a forecast, county, fire, or marine zone.
Schema: https://api.weather.gov/openapi.json#/components/schemas/Zone
type ZoneForecast ¶
type ZoneForecast struct {
Context json.RawMessage `json:"@context,omitempty"`
Geometry string `json:"geometry,omitempty"`
Zone string `json:"zone"`
Updated string `json:"updated"`
Periods []ZoneForecastPeriod `json:"periods"`
}
ZoneForecast models the NWS OpenAPI ZoneForecast schema used as ZoneForecastGeoJson.properties. It is a textual forecast for a zone, not a grid forecast. Periods do not include the numeric weather fields or start/end timestamps of grid forecasts.
Schema: https://api.weather.gov/openapi.json#/components/schemas/ZoneForecast
type ZoneForecastPeriod ¶
type ZoneForecastPeriod struct {
Number int `json:"number"`
Name string `json:"name"`
DetailedForecast string `json:"detailedForecast"`
}
ZoneForecastPeriod models an inline periods entry in the NWS OpenAPI ZoneForecast schema, keeping the NWS period number, label, and forecast text.
Schema: https://api.weather.gov/openapi.json#/components/schemas/ZoneForecast/properties/periods/items
type ZonesService ¶
type ZonesService struct {
// contains filtered or unexported fields
}
ZonesService provides access to NWS zones endpoints. Use the corresponding field on a Client constructed with NewClient.
func (*ZonesService) Get ¶
func (s *ZonesService) Get(ctx context.Context, zoneType, id string) (*Feature[Zone], *Response, error)
Get fetches metadata by NWS zone type and identifier. To use a discovered forecastZone URL directly, call Client.Get with an Feature[Zone].
func (*ZonesService) GetForecast ¶
func (s *ZonesService) GetForecast(ctx context.Context, zoneType, id string) (*Feature[ZoneForecast], *Response, error)
GetForecast retrieves a zone's current forecast without converting its periods into grid forecast periods.
func (*ZonesService) List ¶
func (s *ZonesService) List(ctx context.Context, query url.Values) (*FeatureCollection[Zone], *Response, error)
List returns zones matching NWS query parameters such as area, type, point, and include_geometry. Multi-value filters use comma-separated strings.
func (*ZonesService) ListByType ¶
func (s *ZonesService) ListByType(ctx context.Context, zoneType string, query url.Values) (*FeatureCollection[Zone], *Response, error)
ListByType selects the zone type in the route; query retains the list filters.