Skip to content

Instantly share code, notes, and snippets.

@qneyrat
Created May 15, 2018 14:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qneyrat/319b5c35096af2f1af46ef306d5a61fb to your computer and use it in GitHub Desktop.
Save qneyrat/319b5c35096af2f1af46ef306d5a61fb to your computer and use it in GitHub Desktop.
json rpc 2.0
package main
import (
"log"
"encoding/json"
"errors"
"net/http"
)
const JSONRPCVersion = "2.0"
type JSONRPCRequest struct {
JSONRPC string `json:"jsonrpc"`
Method Method `json:"method"`
Params string `json:"params"`
ID string `json:"id"`
}
type JSONRPCResponse struct {
JSONRPC string `json:"jsonrpc"`
Result string `json:"result"`
Error string `json:"error"`
ID string `json:"id"`
}
type Method string
type JSONRPCServer struct {
Endpoints map[Method]JSONRPCEndpoint
}
func NewJSONRPCServer() *JSONRPCServer {
return &JSONRPCServer{
Endpoints: make(map[Method]JSONRPCEndpoint),
}
}
type JSONRPCEndpoint func(req JSONRPCRequest) JSONRPCResponse
func (s *JSONRPCServer) addEndpoint(method Method, endpoint JSONRPCEndpoint) {
s.Endpoints[method] = endpoint
}
func (s *JSONRPCServer) getEndpoint(method Method) (JSONRPCEndpoint, error) {
e, ok := s.Endpoints[method]
if !ok {
return nil, errors.New("method not allowed")
}
return e, nil
}
func main() {
server := NewJSONRPCServer()
server.addEndpoint("ping", func(req JSONRPCRequest) JSONRPCResponse {
return JSONRPCResponse{
JSONRPC:JSONRPCVersion,
Result:"pong",
ID:req.ID,
}
})
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
var j JSONRPCRequest
if r.Body == nil {
http.Error(w, "please send a JSON RPC 2.0 request", http.StatusBadRequest)
return
}
err := json.NewDecoder(r.Body).Decode(&j)
if err != nil {
http.Error(w, err.Error(), 400)
return
}
if j.JSONRPC != JSONRPCVersion {
http.Error(w, "please send a JSON RPC 2.0 request", http.StatusBadRequest)
return
}
e, err := server.getEndpoint(j.Method)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
}
res := e(j)
json.NewEncoder(w).Encode(res)
})
log.Fatal(http.ListenAndServe(":8001", nil))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment