by semrush

semrush / zenrpc

JSON-RPC 2.0 Server Implementation with SMD support written in Go (go generate)

130 Stars 19 Forks Last release: Not found MIT License 78 Commits 6 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

zenrpc: JSON-RPC 2.0 Server Implementation with SMD support

Go Report Card Build Status codecov GoDoc

is a JSON-RPC 2.0 server library with Service Mapping Description support. It's built on top of
go generate
instead of reflection.

How to Use

Service is struct with RPC methods, service represents RPC namespace.
  1. Install zenrpc generator
    go get github.com/semrush/zenrpc/v2/zenrpc
  2. Import
    into our code with rpc service.
  3. Add trailing comment
    to your service or embed
    into your service struct.
  4. Write your funcs almost as usual.
  5. Do not forget run
    go generate
    for magic

Accepted Method Signatures

func(Service) Method([args]) (, )
func(Service) Method([args]) 
func(Service) Method([args]) 
func(Service) Method([args])
  • Value could be a pointer
  • Error is error or *zenrpc.Error


package main

import ( "flag" "context" "errors" "math" "log" "net/http" "os"



type ArithService struct{ zenrpc.Service }

// Sum sums two digits and returns error with error code as result and IP from context. func (as ArithService) Sum(ctx context.Context, a, b int) (bool, *zenrpc.Error) { r, _ := zenrpc.RequestFromContext(ctx)

return true, zenrpc.NewStringError(a+b, r.Host)


// Multiply multiples two digits and returns result. func (as ArithService) Multiply(a, b int) int { return a * b }

type Quotient struct { Quo, Rem int }

func (as ArithService) Divide(a, b int) (quo *Quotient, err error) { if b == 0 { return nil, errors.New("divide by zero") } else if b == 1 { return nil, zenrpc.NewError(401, errors.New("we do not serve 1")) }

return &Quotient{
    Quo: a / b,
    Rem: a % b,
}, nil


// Pow returns x**y, the base-x exponential of y. If Exp is not set then default value is 2. //zenrpc:exp=2 func (as ArithService) Pow(base float64, exp float64) float64 { return math.Pow(base, exp) }

//go:generate zenrpc

func main() { addr := flag.String("addr", "localhost:9999", "listen address") flag.Parse()

rpc := zenrpc.NewServer(zenrpc.Options{ExposeSMD: true})
rpc.Register("arith", testdata.ArithService{})
rpc.Register("", testdata.ArithService{}) // public
rpc.Use(zenrpc.Logger(log.New(os.Stderr, "", log.LstdFlags)))

http.Handle("/", rpc)

log.Printf("starting arithsrv on %s", *addr)
log.Fatal(http.ListenAndServe(*addr, nil))


Magic comments

All comments are optional.

Method comments

Struct comments type MyService struct {} //zenrpc

Need to browse your api and do some test api calls?

We recommend to use SMDBox. It is Swagger-like JSON RPC API browser, compatible with smd scheme, generated by zenrpc.

JSON-RPC 2.0 Supported Features

  • [x] Requests
    • [x] Single requests
    • [x] Batch requests
    • [x] Notifications
  • [x] Parameters
    • [x] Named
    • [x] Position
    • [x] Default values
  • [x] SMD Schema
    • [x] Input
    • [x] Output
    • [x] Codes
    • [ ] Scopes for OAuth

Server Library Features

  • [x] go generate
  • [ ] Transports
    • [x] HTTP
    • [x] WebSocket
    • [ ] RabbitMQ
  • [x] Server middleware
    • [x] Basic support
    • [x] Metrics
    • [x] Logging

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.