Skip to navigation

What is gRPC?

View as Markdown
Enterprise feature for SDKs

Using this feature in generated SDKs requires the Enterprise plan. To get started, reach out to support@buildwithfern.com.

Fern only supports gRPC SDK generation for .NET/C#. Protobuf specs can be used for documentation generation in all languages. File an issue to request additional languages.

gRPC is a modern, open-source, high-performance Remote Procedure Call (RPC) framework that can run in any environment. It uses Protocol Buffers (protobuf) as the interface definition language and supports multiple programming languages. Fern is compatible with gRPC services and can generate SDKs and documentation from your .proto files.

For a working example, see the gRPC demo docs and its GitHub repository.

Below is an example of a gRPC service definition:

user_service.proto
syntax = "proto3";
package userservice.v1;
// User service for managing user accounts
service UserService {
// Create a new user account
rpc CreateUser(CreateUserRequest) returns (User);
// Get user by ID
rpc GetUser(GetUserRequest) returns (User);
// List users with pagination
rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);
// Update user information
rpc UpdateUser(UpdateUserRequest) returns (User);
// Delete a user account
rpc DeleteUser(DeleteUserRequest) returns (google.protobuf.Empty);
// Stream user events (server streaming)
rpc StreamUserEvents(StreamUserEventsRequest) returns (stream UserEvent);
// Upload user data (client streaming)
rpc UploadUserData(stream UploadUserDataRequest) returns (UploadUserDataResponse);
// Real-time chat (bidirectional streaming)
rpc Chat(stream ChatMessage) returns (stream ChatMessage);
}
// Messages for user operations
message User {
string id = 1;
string email = 2;
string name = 3;
int32 age = 4;
google.protobuf.Timestamp created_at = 5;
UserStatus status = 6;
}
message CreateUserRequest {
string email = 1;
string name = 2;
int32 age = 3;
}
message GetUserRequest {
string id = 1;
}
message ListUsersRequest {
int32 page_size = 1;
string page_token = 2;
string filter = 3;
}
message ListUsersResponse {
repeated User users = 1;
string next_page_token = 2;
int32 total_count = 3;
}
message UpdateUserRequest {
string id = 1;
User user = 2;
google.protobuf.FieldMask update_mask = 3;
}
message DeleteUserRequest {
string id = 1;
}
message StreamUserEventsRequest {
string user_id = 1;
repeated UserEventType event_types = 2;
}
message UserEvent {
string id = 1;
string user_id = 2;
UserEventType type = 3;
google.protobuf.Timestamp timestamp = 4;
google.protobuf.Any data = 5;
}
message UploadUserDataRequest {
oneof data {
UserDataChunk chunk = 1;
UserDataMetadata metadata = 2;
}
}
message UserDataChunk {
bytes data = 1;
int64 offset = 2;
}
message UserDataMetadata {
string filename = 1;
int64 total_size = 2;
string content_type = 3;
}
message UploadUserDataResponse {
string file_id = 1;
int64 bytes_uploaded = 2;
}
message ChatMessage {
string id = 1;
string user_id = 2;
string room_id = 3;
string content = 4;
google.protobuf.Timestamp timestamp = 5;
ChatMessageType type = 6;
}
// Enums
enum UserStatus {
USER_STATUS_UNSPECIFIED = 0;
USER_STATUS_ACTIVE = 1;
USER_STATUS_INACTIVE = 2;
USER_STATUS_SUSPENDED = 3;
}
enum UserEventType {
USER_EVENT_TYPE_UNSPECIFIED = 0;
USER_EVENT_TYPE_CREATED = 1;
USER_EVENT_TYPE_UPDATED = 2;
USER_EVENT_TYPE_DELETED = 3;
USER_EVENT_TYPE_LOGIN = 4;
USER_EVENT_TYPE_LOGOUT = 5;
}
enum ChatMessageType {
CHAT_MESSAGE_TYPE_UNSPECIFIED = 0;
CHAT_MESSAGE_TYPE_TEXT = 1;
CHAT_MESSAGE_TYPE_IMAGE = 2;
CHAT_MESSAGE_TYPE_FILE = 3;
CHAT_MESSAGE_TYPE_SYSTEM = 4;
}

Get started with fern init

fern init creates a fern/ folder with a generators.yml that generates a C# SDK. Run it from your project root.

terminal
# Sample gRPC service
fern init --grpc
# Your own .proto file or directory of .proto files
fern init --proto ./proto

--grpc creates a sample unary service. --proto takes a local path, copies the .proto files into fern/proto/, and adds the google/api protos if they’re imported and missing. target is set to the file that defines a service; when several files define one, target is omitted and every file is compiled. The two flags can’t be combined with each other or with --openapi, --fern-definition, --docs, --mintlify, or --readme. See the generators.yml reference for configuration options.

Then generate the SDK:

terminal
fern generate

fern generate compiles the .proto files on your machine, downloading buf the first time, and builds the SDK in Fern’s cloud. The SDK is written to sdks/csharp.

Supported proto features

The C# SDK supports unary RPCs. Streaming RPCs (server, client, and bidirectional) aren’t supported yet. fern init --proto warns you if your files use them.

Other languages

Only the C# SDK contains a gRPC client. For other languages, Fern converts the proto to OpenAPI and generates a REST client that follows the google.api.http routes. These clients send HTTP/JSON, which a native gRPC server doesn’t accept, so they require a gateway in front of the server that translates HTTP/JSON to gRPC, such as grpc-gateway or Envoy’s gRPC-JSON transcoder. Streaming RPCs are generated as plain POST methods and don’t stream.

Get help

If you run into issues, reach out to support@buildwithfern.com.