buf-check-strictrpc

command module
v0.0.0-...-a5c437e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 5, 2024 License: MIT Imports: 2 Imported by: 0

README

buf-check-strictrpc Actions Go Report Card

This repository contains a custom buf check plugin designed to enforce a stricter set of lint rules for Protobuf RPCs, particularly when using frameworks like gRPC or Connect.

While the buf linter enforces some RPC_ rules, this plugin introduces additional constraints:

  1. Files containing a service definition must have a filename ending with _service.proto.
  2. Each file can only contain one service definition, which must appear at the top before any message definitions.
  3. For every RPC method, there must be exactly two associated messages, named after the method and suffixed with Request and Response.
  4. Optionally, a third message may be present, which must be suffixed with ErrorDetails.
  5. Messages in the file must be listed in the same order as their corresponding RPC methods.
Plugin options

Useful options to configure the plugin:

Option Default Description
disable_streaming false Disables streaming RPCs. (Some people just don't like em)
allow_protobuf_empty false Allows usage of google.protobuf.Empty in requests or responses.
Example

Given a dragon_service.proto file:

service DragonService {
  rpc GetDragon(GetDragonRequest) returns (GetDragonResponse) {}
  rpc TrainDragon(TrainDragonRequest) returns (TrainDragonResponse) {}
}

message GetDragonRequest {}

message GetDragonResponse {}

message TrainDragonRequest {}

message TrainDragonResponse {}

// This message is optional.
message TrainDragonErrorDetails {}
Preparing a WASM binary

Compile the Go plugin to a WASM binary:

GOOS=wasip1 GOARCH=wasm go build -o buf-check-strictrpc.wasm main.go

Let's try it out!

wasmtime buf-check-strictrpc.wasm --help

Enforces an opinionated structure for RPC definitions, including strict file naming, single-service per file, and consistent request/response message naming patterns.

Commands:

  check
  info
  list-categories
  list-rules

Flags:

      --format string   The format to use for requests, responses, and specs. Must be one of ["binary", "json"]. (default "binary")
      --protocol        Print the protocol to stdout and exit.
      --spec            Print the spec to stdout in the specified format and exit.
  -h, --help            Show this help.

Neat, let's see what the protocol looks like:

wasmtime buf-check-strictrpc.wasm --protocol
1

Okay, now let's try something more interesting, what does the spec look like?

wasmtime buf-check-strictrpc.wasm --spec --format=json | jq

Output:

{
  "procedures": [
    {
      "path": "/buf.plugin.check.v1.CheckService/Check",
      "args": ["check"]
    },
    {
      "path": "/buf.plugin.check.v1.CheckService/ListRules",
      "args": ["list-rules"]
    },
    {
      "path": "/buf.plugin.check.v1.CheckService/ListCategories",
      "args": ["list-categories"]
    },
    {
      "path": "/buf.plugin.info.v1.PluginInfoService/GetPluginInfo",
      "args": ["info"]
    }
  ]
}
Using WASM binary with buf

We could compile the plugin to normal Go binary, but what's the fun in that? So let's use wasmtime to run the WASM binary:

GOOS=wasip1 GOARCH=wasm go build -o ./examples/buf-check-strictrpc.wasm main.go

buf lint ./examples/dragon.proto
examples/dragon.proto:1:1:service "dragon" must end with _service.proto. (wasmtime ./examples/buf-check-strictrpc.wasm)

Yikes, we forgot to add the _service.proto suffix to our file!

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL
JackTT - Gopher 🇻🇳