Skip to content

HTTP Transport

HttpServer wraps a Server and serves RPC over HTTP. For background on available transports, see the transports overview on the main vgi-rpc site.

httpServer := vgirpc.NewHttpServer(server)
http.ListenAndServe(":8080", httpServer)

URL Routing

Routes use an empty prefix by default:

Route Purpose
POST /{method} Unary RPC call
POST /{method}/init Stream initialization
POST /{method}/exchange Exchange continuation
POST /__describe__ Introspection

All request and response bodies use Content-Type: application/vnd.apache.arrow.stream.

Request Compression

The server transparently decompresses request bodies sent with Content-Encoding: zstd. The Python vgi-rpc client enables zstd compression by default (level 3), so this is handled automatically.

State Tokens

HTTP is stateless, so exchange streams carry an HMAC-signed state token in batch custom metadata (vgi_rpc.stream_state). The server serializes the ExchangeState via encoding/gob, signs it, and returns it to the client. The client sends the token back with each exchange request.

Important

Call vgirpc.RegisterStateType for every concrete type used in your state (and any types they embed) before the first HTTP stream request:

func init() {
    vgirpc.RegisterStateType(&myExchangeState{})
}

Signing Key

By default, NewHttpServer generates a random 32-byte signing key. For multi-instance deployments, use NewHttpServerWithKey with a shared key:

httpServer := vgirpc.NewHttpServerWithKey(server, sharedKey)

Token TTL

State tokens have a configurable time-to-live. Use SetTokenTTL to adjust:

httpServer.SetTokenTTL(30 * time.Minute)

Full Example

package main

import (
    "net/http"
    "github.com/Query-farm/vgi-rpc/vgirpc"
)

func init() {
    vgirpc.RegisterStateType(&myState{})
}

func main() {
    server := vgirpc.NewServer()
    // ... register methods ...

    httpServer := vgirpc.NewHttpServer(server)
    http.ListenAndServe(":8080", httpServer)
}