Skip to content

Instantly share code, notes, and snippets.

@wgeorgecook
Created July 2, 2020 06:15
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 wgeorgecook/bafc9cbbf18a10e78a9e01ca0b36fd18 to your computer and use it in GitHub Desktop.
Save wgeorgecook/bafc9cbbf18a10e78a9e01ca0b36fd18 to your computer and use it in GitHub Desktop.
Creates an HTTP server that listens on port :8000 for routes matching "/hello/{person}". If it matches the route, returns json {"hello": {person}}. If not, returns an error.
package main
import (
"encoding/json"
"fmt"
"github.com/gorilla/mux"
"log"
"net/http"
"os"
"os/signal"
"strings"
"syscall"
"time"
)
type ResponseJson struct {
Hello string `json:"hello,omitempty"`
Error string `json:"error,omitempty"`
}
func main() {
var done chan os.Signal
done = make(chan os.Signal)
r := mux.NewRouter()
r.Methods("POST")
r.NotFoundHandler = http.HandlerFunc(NotFoundHandler) // not sure why this isn't working but srug
r.HandleFunc("/hello/{greeting}", HelloHandler)
srv := &http.Server{
Handler: r,
Addr: ":8000",
WriteTimeout: 30 * time.Second,
ReadTimeout: 30 * time.Second,
}
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()
log.Print("Server Started")
<-done
log.Print("Server Stopped")
}
func NotFoundHandler(w http.ResponseWriter, r *http.Request) {
log.Printf("unknown route")
// create a new error
resp := ResponseJson{Error: "I don't have that route"}
// marshal to json
respJson, err := json.Marshal(resp)
if err != nil {
panic(fmt.Sprintf("could not marshal 404 response: %v", err))
}
// set the header to 404 response code and return the error response
w.WriteHeader(404)
w.Write(respJson)
return
}
func HelloHandler(w http.ResponseWriter, r *http.Request) {
defer func() {
if r := recover(); r != nil {
log.Printf("panic recovered in HelloHandler: %v", r)
w.WriteHeader(500)
// marshal error to the request
var resp ResponseJson
resp.Error = "Internal service error"
respJson, _ := json.Marshal(resp) // ignoring error here because I'm not sure how to avoid json marshalling hell
// actually write the error back
w.Write(respJson)
}
}()
log.Println("/hello endpoint hit")
// check our URL
greetingURL := r.URL.Path
greetingSlice := strings.Split(greetingURL, "/")
greeting := greetingSlice[2] // hardcode this for expediency
// Check for END
if strings.ToLower(greeting) == "end" {
log.Printf("received end request and panicking")
panic("panicking")
}
// set our response header
w.Header().Set("Content-Type", "application/json")
// create some json to send back
resp := ResponseJson{Hello: greeting}
respJson, err := json.Marshal(resp)
if err != nil {
log.Printf("could not marshal response: %v", err)
panic("panicking")
}
log.Printf("Hello, %v!", greeting)
// return JSON
w.WriteHeader(200)
w.Write(respJson)
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment