diff --git a/serverutil/json.go b/serverutil/json.go
new file mode 100644
index 0000000000000000000000000000000000000000..e1d0f85f377abcea85a39004b6171f18413a17c0
--- /dev/null
+++ b/serverutil/json.go
@@ -0,0 +1,37 @@
+package serverutil
+
+import (
+	"encoding/json"
+	"net/http"
+)
+
+// DecodeJSONRequest decodes a JSON object from an incoming HTTP POST
+// request and return true when successful. In case of errors, it will
+// write an error response to w and return false.
+func DecodeJSONRequest(w http.ResponseWriter, r *http.Request, obj interface{}) bool {
+	if r.Method != "POST" {
+		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
+		return false
+	}
+	if r.Header.Get("Content-Type") != "application/json" {
+		http.Error(w, "Need JSON request", http.StatusBadRequest)
+		return false
+	}
+
+	if err := json.NewDecoder(r.Body).Decode(obj); err != nil {
+		http.Error(w, err.Error(), http.StatusBadRequest)
+		return false
+	}
+
+	return true
+}
+
+// EncodeJSONResponse writes an application/json response to w.
+func EncodeJSONResponse(w http.ResponseWriter, obj interface{}) {
+	w.Header().Set("Content-Type", "application/json")
+	w.Header().Set("Pragma", "no-cache")
+	w.Header().Set("Cache-Control", "no-store")
+	w.Header().Set("Expires", "-1")
+	w.Header().Set("X-Content-Type-Options", "nosniff")
+	json.NewEncoder(w).Encode(obj)
+}