Protoreg

protoreg provides a shared protobuf registry, enabling other plugins to access proto definitions at runtime, making it ideal for building custom gRPC interceptors, middleware, and dynamic message handling.

Features

  • Parses and registers .proto files at startup

  • Provides a shared protoregistry accessible by other plugins

  • Supports multiple import paths for proto dependencies

  • Automatically resolves and registers proto file dependencies

  • Exposes service and method descriptors for reflection-based operations

  • Thread-safe registry access

Use Cases

  • Custom gRPC Interceptors: Build interceptors that need to inspect or modify messages based on their proto definitions

  • Dynamic Message Handling: Deserialize and serialize protobuf messages without compile-time generated code

  • Request/Response Validation: Validate gRPC requests against proto schemas

  • Logging & Monitoring: Create detailed logs with field-level message inspection

Configuration

The plugin is configured under the protoreg section in your .rr.yaml configuration file:

Configuration Options

proto_path (required)

A list of directories where the plugin will search for proto files and their dependencies. These paths work similarly to the --proto-path/-I flag in protoc.

Why it's needed: Proto files often import other proto files (e.g., import "google/protobuf/timestamp.proto"). The import paths tell the parser where to find these dependencies. You typically need:

  • A path containing your service definitions

  • A path containing shared/common message definitions

  • Paths to any third-party proto files (like Google's well-known types)

files (required)

A list of proto files to parse and register. Paths are relative to the proto_path directories. This works similarly to passing variadic proto files argument in protoc.

Why it's needed: This explicitly declares which proto files define the services and messages you want to access at runtime. The plugin will:

  1. Parse each listed proto file

  2. Automatically resolve and register all imported dependencies

  3. Build a registry of all services and their methods

Example: Project Structure

A typical project structure when using this plugin:

proto/commonapis/common/v1/message.proto:

proto/serviceapis/service/v1/service.proto:

Configuration (.rr.yaml):

Using the Registry in Your Plugin

Other plugins can depend on protoreg to access the registry. Here's how to use it in a custom plugin:

Registry Interface

The plugin exposes the following interface:

Example: gRPC Interceptor

Here's an example of using the registry in a custom gRPC interceptor to log request details:

Troubleshooting

"proto path does not exist"

Ensure all paths in proto_path exist and are accessible. Paths can be absolute or relative to the RoadRunner working directory.

"proto file does not exist"

The proto file must exist in one of the configured proto_path. Check that:

  1. The file path in files is relative to an import path, not an absolute path

  2. The directory structure matches the import path

"file already registered"

This occurs when the same proto file is included multiple times (e.g., listed in files and also imported by another file). The plugin handles dependencies automatically, so you typically only need to list your top-level service definitions in the files section.

License

MIT License - see LICENSE file for details.

Last updated

Was this helpful?