https://github.com/varavelio/vdl-plugin-rpc-go
Plugin to generate VDL RPC for Golang
https://github.com/varavelio/vdl-plugin-rpc-go
api codegen go golang rpc varavel vdl vdl-plugin vdl-rpc
Last synced: 14 days ago
JSON representation
Plugin to generate VDL RPC for Golang
- Host: GitHub
- URL: https://github.com/varavelio/vdl-plugin-rpc-go
- Owner: varavelio
- License: mit
- Created: 2026-03-28T15:25:38.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-03-28T17:03:18.000Z (3 months ago)
- Last Synced: 2026-03-28T19:05:37.127Z (3 months ago)
- Topics: api, codegen, go, golang, rpc, varavel, vdl, vdl-plugin, vdl-rpc
- Language: TypeScript
- Homepage:
- Size: 7.81 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
VDL RPC Golang Plugin
Generate Go RPC clients and RPC servers from annotation-based VDL services.
This plugin is RPC-focused.
It does not generate Go data models (types/enums/constants). Instead, it reuses the types generated by [`varavelio/vdl-plugin-go`](https://github.com/varavelio/vdl-plugin-go).
## Quick Start
1. Generate Go types first with `varavelio/vdl-plugin-go`.
2. Generate the RPC client package (`target "client"`) and/or server package (`target "server"`).
3. Run your normal VDL generation command (example: `vdl generate`).
```vdl
const config = {
version 1
plugins [
{
src "varavelio/vdl-plugin-go@v0.1.3"
schema "./schema.vdl"
outDir "./internal/types"
options {
package "types"
}
}
{
src "varavelio/vdl-plugin-rpc-go@v0.1.2"
schema "./schema.vdl"
outDir "./internal/client"
options {
package "client"
target "client"
typesImport "example.com/project/internal/types"
}
}
{
src "varavelio/vdl-plugin-rpc-go@v0.1.2"
schema "./schema.vdl"
outDir "./internal/server"
options {
package "server"
target "server"
typesImport "example.com/project/internal/types"
}
}
]
}
```
If you only need one side, keep only one RPC plugin block (`client` or `server`).
## Plugin Options
| Option | Type | Required | Default | What it changes |
| ------------- | -------- | -------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `target` | `string` | yes | - | Selects generation target. Must be `client` or `server`. |
| `typesImport` | `string` | no | - | Go import path for the package generated by `varavelio/vdl-plugin-go`. When omitted/empty, RPC types are resolved from the same package. |
| `package` | `string` | no | `vdlrpc` | Sets the package name used in generated RPC files (must be a valid Go package). |
| `jsonPackage` | `string` | no | `encoding/json` | Sets the Go package used for JSON marshal/unmarshal. It is always imported as `json "..."`. |
### `typesImport` behavior
- Omitted or empty (`""`): same-package mode. Generated code does not emit a types import and uses direct type names like `MessagesSendInput`.
- Non-empty: imported-types mode. Generated code imports `typesImport` as `vdltypes` and uses `vdltypes.MessagesSendInput`.
Use same-package mode when you generate Go types and RPC output into the same package. Use imported-types mode when RPC is generated in a different package.
### `jsonPackage` behavior
- Omitted: generated code imports `encoding/json` as `json`.
- Non-empty: generated code imports the configured package as `json`.
- Empty or whitespace-only: falls back to `encoding/json`.
This matches the native Go plugin behavior and lets you swap in compatible JSON implementations like `github.com/goccy/go-json` without changing generated call sites.
## Generated Files
- `target "client"` writes `client.go`.
- `target "server"` writes `server.go`.
- If your schema has no discovered `@rpc`, `@proc` or `@stream` operations, no RPC file is emitted.
## What You Get
For `target "client"`:
- `NewClient(baseURL).Build()` to create a typed RPC client.
- Typed procedure builders and stream builders under `client.RPCs.()`.
- Headers and header providers at global, RPC, and operation levels.
- Interceptors, retry/timeout policies for procs, reconnect policies for streams.
- Stream lifecycle hooks and max message size controls.
For `target "server"`:
- `NewServer[Props]()` with typed handler contexts.
- Typed registration APIs for procedures and streams.
- Middleware support at global, RPC, procedure, stream, and stream-emit levels.
- `SetStreamConfig` and `SetErrorHandler` at global and RPC scope.
- `NewNetHTTPAdapter(...)` + `HandleRequest(...)` integration for `net/http`.
Both targets also include generated operation catalogs:
- `VDLPaths` for static operation paths.
- `VDLProcedures` and `VDLStreams` with operation metadata.
- Non-marker operation annotations preserved as `Annotation` values.
## RPC Annotation Model
This plugin follows the VDL RPC annotation model:
- `@rpc` marks a top-level type as an RPC service.
- `@proc` marks a field as a request-response operation.
- `@stream` marks a field as a server-streaming operation.
```vdl
@rpc
type Messages {
@proc
send {
input {
roomId string
text string
}
output {
accepted bool
}
}
@stream
events {
input {
roomId string
}
output {
text string
}
}
}
```
Validation rules enforced by the plugin:
- `@rpc` types must be objects.
- An operation field can be `@proc` or `@stream`, but not both.
- Operation nodes must be objects.
- `input` and `output`, when present, must be objects.
If an operation omits `input` and/or `output`, generated code uses `Void` for the missing payload.
## Minimal Usage Example
```go
package main
import (
"context"
"net/http"
rpcclient "example.com/project/internal/client"
rpcserver "example.com/project/internal/server"
vdltypes "example.com/project/internal/types"
)
func example() {
server := rpcserver.NewServer[struct{}]()
server.RPCs.Messages().Procs.Send().Handle(
func(c *rpcserver.MessagesSendHandlerContext[struct{}]) (vdltypes.MessagesSendOutput, error) {
return vdltypes.MessagesSendOutput{Accepted: true}, nil
},
)
mux := http.NewServeMux()
mux.HandleFunc("POST /rpc/{rpc}/{operation}", func(w http.ResponseWriter, r *http.Request) {
adapter := rpcserver.NewNetHTTPAdapter(w, r)
_ = server.HandleRequest(r.Context(), struct{}{}, r.PathValue("rpc"), r.PathValue("operation"), adapter)
})
client := rpcclient.NewClient("http://localhost:8080/rpc").Build()
_, _ = client.RPCs.Messages().Procs.Send().Execute(
context.Background(),
vdltypes.MessagesSendInput{RoomId: "room-1", Text: "hello"},
)
}
```
`baseURL` in `NewClient(baseURL)` should point to your RPC prefix (for example: `/rpc`). The generated client appends `/{RPC}/{operation}` automatically.
## License
This plugin is released under the MIT License. See [LICENSE](LICENSE).