Skip to content

Instantly share code, notes, and snippets.

@shindakun
Created February 22, 2021 00:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shindakun/4ebd21c2939bb56936f2268ed61b2199 to your computer and use it in GitHub Desktop.
Save shindakun/4ebd21c2939bb56936f2268ed61b2199 to your computer and use it in GitHub Desktop.
FROM golang:1.16 as compile
WORKDIR /weather
COPY . /weather
RUN CGO_ENABLED=0 GOOS=linux GOPROXY=https://proxy.golang.org go build -o weather main.go
FROM alpine:latest
EXPOSE 8080
RUN apk --no-cache add ca-certificates && addgroup -S weather && adduser -S weather -G weather
USER weather
WORKDIR /weather
COPY --from=compile /weather/weather .
ENTRYPOINT ["./weather"]
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
)
const (
port = ":8080"
defaultState = "NY"
)
// APIResponse struct uses only the fields we need to fullfil the objective
type APIResponse struct {
Features []struct {
Properties struct {
Headline string `json:"headline"`
} `json:"properties"`
} `json:"features"`
}
// AlertsResponse struct format for our output
type AlertsResponse struct {
Alerts []string `json:"alerts"`
}
// getAlerts retrieves weather alerts by state and returns []byte's of JSON
func getAlerts(state string) ([]byte, error) {
if state == "" {
state = defaultState
}
url := fmt.Sprintf("https://api.weather.gov/alerts/active?area=%s", state)
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var alert APIResponse
err = json.Unmarshal(body, &alert)
if err != nil {
return nil, err
}
var alerts AlertsResponse
for c := range alert.Features {
alerts.Alerts = append(alerts.Alerts, alert.Features[c].Properties.Headline)
}
jsn, err := json.Marshal(alerts)
if err != nil {
return nil, err
}
if err != nil {
return nil, err
}
return jsn, nil
}
func main() {
http.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "pong")
})
http.HandleFunc("/api/weather", func(w http.ResponseWriter, r *http.Request) {
// Could get state from a URL param but that's not the spec.
jsn, err := getAlerts("")
if err != nil {
log.Println(err)
http.Error(w, http.StatusText(http.StatusInternalServerError),
http.StatusInternalServerError)
} else {
fmt.Fprintf(w, string(jsn))
}
})
err := http.ListenAndServe(port, nil)
if err != nil {
log.Fatal(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment