Build a JSON over HTTP Server

Distributed Services with Go — by Travis Jeffery (12 / 84)

​ ​package​ server

​ ​import​ (
​ ​"encoding/json"​
​ ​"net/http"​

​ ​"github.com/gorilla/mux"​
​ )

​ ​func​ NewHTTPServer(addr ​string​) *http.Server {
​ httpsrv := newHTTPServer()
​ r := mux.NewRouter()
​ r.HandleFunc(​"/"​, httpsrv.handleProduce).Methods(​"POST"​)
​ r.HandleFunc(​"/"​, httpsrv.handleConsume).Methods(​"GET"​)
​ ​return​ &http.Server{
​ Addr: addr,
​ Handler: r,
​ }
​ }
​ ​type​ httpServer ​struct​ {
​ Log *Log
​ }

​ ​func​ newHTTPServer() *httpServer {
​ ​return​ &httpServer{
​ Log: NewLog(),
​ }
​ }

​ ​type​ ProduceRequest ​struct​ {
​ Record Record ​`json:"record"`​
​ }

​ ​type​ ProduceResponse ​struct​ {
​ Offset ​uint64​ ​`json:"offset"`​
​ }

​ ​type​ ConsumeRequest ​struct​ {
​ Offset ​uint64​ ​`json:"offset"`​
​ }

​ ​type​ ConsumeResponse ​struct​ {
​ Record Record ​`json:"record"`​
​ }
​ ​func​ (s *httpServer) handleProduce(w http.ResponseWriter, r *http.Request) {
​ ​var​ req ProduceRequest
​ err := json.NewDecoder(r.Body).Decode(&req)
​ ​if​ err != nil {
​ http.Error(w, err.Error(), http.StatusBadRequest)
​ ​return​
​ }
​ off, err := s.Log.Append(req.Record)
​ ​if​ err != nil {
​ http.Error(w, err.Error(), http.StatusInternalServerError)
​ ​return​
​ }
​ res := ProduceResponse{Offset: off}
​ err = json.NewEncoder(w).Encode(res)
​ ​if​ err != nil {
​ http.Error(w, err.Error(), http.StatusInternalServerError)
​ ​return​
​ }
​ }
​ ​func​ (s *httpServer) handleConsume(w http.ResponseWriter, r *http.Request) {
​ ​var​ req ConsumeRequest
​ err := json.NewDecoder(r.Body).Decode(&req)
​ ​if​ err != nil {
​ http.Error(w, err.Error(), http.StatusBadRequest)
​ ​return​
​ }
​ record, err := s.Log.Read(req.Offset)
​ ​if​ err == ErrOffsetNotFound {
​ http.Error(w, err.Error(), http.StatusNotFound)
​ ​return​
​ }
​ ​if​ err != nil {
​ http.Error(w, err.Error(), http.StatusInternalServerError)
​ ​return​
​ }
​ res := ConsumeResponse{Record: record}
​ err = json.NewEncoder(w).Encode(res)
​ ​if​ err != nil {
​ http.Error(w, err.Error(), http.StatusInternalServerError)
​ ​return​
​ }
​ }

We create timely, practical books and learning resources on classic and cutting-edge topics to help you practice your craft and accelerate your career.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store