gRPC/Protobuf Export
Export your FakeDataDSL schemas to Protocol Buffer definitions for use with gRPC microservices.
Quick Start
# Export single schema
fake_data_dsl export User -d schemas/ -f protobuf -o user.proto
# Export all schemas
fake_data_dsl export --all -d schemas/ -f protobuf -o all.proto
Generated Output
For this schema:
User:
id: uuid
name: name
email: email
age: number(18..65)
active: boolean
role: enum(admin, user, moderator)
The exporter generates:
syntax = "proto3";
package generated;
import "google/protobuf/timestamp.proto";
enum UserRole {
USERROLE_UNSPECIFIED = 0;
USERROLE_ADMIN = 1;
USERROLE_USER = 2;
USERROLE_MODERATOR = 3;
}
message User {
string id = 1;
string name = 2;
string email = 3;
int64 age = 4;
bool active = 5;
UserRole role = 6;
}
service UserService {
rpc GetUser(GetUserRequest) returns (User);
rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);
rpc GenerateUser(GenerateUserRequest) returns (User);
rpc GenerateManyUsers(GenerateManyUsersRequest) returns (stream User);
}
message GetUserRequest {
string id = 1;
}
message ListUsersRequest {
int32 page = 1;
int32 page_size = 2;
}
message ListUsersResponse {
repeated User users = 1;
int32 total_count = 2;
int32 page = 3;
int32 page_size = 4;
}
message GenerateUserRequest {
optional int64 seed = 1;
optional string mode = 2;
map<string, string> overrides = 3;
}
message GenerateManyUsersRequest {
int32 count = 1;
optional int64 seed = 2;
optional string mode = 3;
}
Ruby API
Single Schema
schema = FakeDataDSL.load("schemas/user.dsl")
exporter = FakeDataDSL::Export::Protobuf.new(
schema,
registry: registry,
package: "myapp.v1",
go_package: "github.com/myapp/proto/v1",
with_service: true
)
proto = exporter.export
File.write("user.proto", proto)
All Schemas
proto = FakeDataDSL::Export::Protobuf.export_all(
registry,
package: "myapp.v1",
go_package: "github.com/myapp/proto/v1",
with_service: true
)
File.write("all.proto", proto)
Options
| Option | Description | Default |
|---|---|---|
package |
Proto package name | "generated" |
go_package |
Go package path | nil |
syntax |
Proto syntax version | "proto3" |
with_service |
Generate gRPC service | true |
Type Mapping
| FakeDataDSL | Protobuf |
|---|---|
text, name, email, etc. |
string |
uuid, ulid, nanoid |
string |
number, integer |
int64 |
int, int32 |
int32 |
float, double, money |
double |
boolean |
bool |
timestamp, datetime |
google.protobuf.Timestamp |
date, time |
string |
binary, base64 |
bytes |
array(T) |
repeated T |
enum(a, b, c) |
Custom enum |
SchemaRef |
Message reference |
Arrays
Arrays map to repeated fields:
Tags:
items: array(text, 1..10)
Becomes:
message Tags {
repeated string items = 1;
}
Nested Schemas
Schema references become message references:
Address:
street: street
city: city
Person:
name: name
address: Address
Becomes:
message Address {
string street = 1;
string city = 2;
}
message Person {
string name = 1;
Address address = 2;
}
Enums
Enums are extracted and generated separately:
User:
role: enum(admin, user, moderator)
Becomes:
enum UserRole {
USERROLE_UNSPECIFIED = 0; // Required zero value
USERROLE_ADMIN = 1;
USERROLE_USER = 2;
USERROLE_MODERATOR = 3;
}
message User {
UserRole role = 1;
}
Using with gRPC
Generate the .proto file:
fake_data_dsl export --all -d schemas/ -f protobuf -o service.protoCompile to your language:
# Go protoc --go_out=. --go-grpc_out=. service.proto
# Ruby grpc_tools_ruby_protoc --ruby_out=. --grpc_out=. service.proto
# Python python -m grpc_tools.protoc --python_out=. --grpc_python_out=. service.proto
3. Implement the service using FakeDataDSL for data generation.
## Example gRPC Server (Ruby)
```ruby
require 'grpc'
require_relative 'service_services_pb'
require 'fake_data_dsl'
class DataGenerationService < Generated::DataGenerationService::Service
def initialize
@registry = FakeDataDSL::Registry.new
@registry.load_dir("schemas/")
end
def generate_user(request, _call)
schema = @registry.schema("User")
data = schema.generate(
seed: request.seed.zero? ? nil : request.seed,
mode: request.mode.empty? ? :random : request.mode.to_sym
)
Generated::User.new(data)
end
def generate_many_users(request, _call)
schema = @registry.schema("User")
return enum_for(:generate_many_users, request, _call) unless block_given?
schema.generate_stream(count: request.count).each do |data|
yield Generated::User.new(data)
end
end
end
server = GRPC::RpcServer.new
server.add_http2_port('0.0.0.0:50051', :this_port_is_insecure)
server.handle(DataGenerationService.new)
server.run_till_terminated