Skip to content

Instantly share code, notes, and snippets.

@dbalan
Created September 2, 2015 19:49
Show Gist options
  • Save dbalan/fcd2cd07290aa0aa344e to your computer and use it in GitHub Desktop.
Save dbalan/fcd2cd07290aa0aa344e to your computer and use it in GitHub Desktop.
Simple KV API in golang
package main
import (
"fmt"
"net/http"
"sync"
)
var (
KeyMap = map[string]string{}
RWLock sync.RWMutex
)
func getHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
http.Error(w, "Method not implemented", http.StatusBadRequest)
return
}
// RWLock reads
RWLock.RLock()
defer RWLock.RUnlock()
err := r.ParseForm()
if err != nil {
http.Error(w, "error parsing form", http.StatusInternalServerError)
return
}
k, ok := r.Form["key"]
if !ok || len(k) != 1 {
http.Error(w, "No keyname or multiple keyname to return", http.StatusBadRequest)
return
}
key := k[0]
value, ok := KeyMap[key]
if !ok {
http.Error(w, "Empty key", http.StatusNotFound)
return
}
fmt.Fprintf(w, "%s\n", value)
}
func setHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
http.Error(w, "method not implemented", http.StatusBadRequest)
return
}
// Lock for writes
RWLock.Lock()
defer RWLock.Unlock()
err := r.ParseForm()
if err != nil {
http.Error(w, "error parsing form", http.StatusInternalServerError)
return
}
for k, v := range r.Form {
KeyMap[k] = v[0]
fmt.Fprintf(w, "set key %s as %s\n", k, v[0])
}
}
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "404 try /set, /get", http.StatusNotFound)
})
http.HandleFunc("/get", getHandler)
http.HandleFunc("/set", setHandler)
fmt.Println("starting server...")
http.ListenAndServe(":4000", nil)
}
package main
import (
"bytes"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
)
func TestGetEmpty(t *testing.T) {
req, _ := http.NewRequest("GET", "get?key=empty", nil)
rec := httptest.NewRecorder()
getHandler(rec, req)
if rec.Code != 404 {
t.Error("Non empty response for empty key")
}
}
func TestSetGet(t *testing.T) {
req, _ := http.NewRequest("GET", "/set?hello=world", nil)
setRec := httptest.NewRecorder()
setHandler(setRec, req)
if setRec.Code != 200 {
t.Error("failed seting value, got return:", setRec.Code)
}
req, _ = http.NewRequest("GET", "/get?key=hello", nil)
getRec := httptest.NewRecorder()
getHandler(getRec, req)
data, err := ioutil.ReadAll(getRec.Body)
if err != nil {
t.Error("error while reading get response!", err)
}
if bytes.Compare(data, []byte("world\n")) != 0 {
t.Errorf("get expected: hello=world got hello=%s\n", data)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment