Overlay Customizations

Use overlay files to modify your gRPC specifications without editing the original Proto files

Overlays allow you to modify your gRPC specifications without directly editing the original Protocol Buffer files. This is useful for:

  • Adding Fern-specific extensions
  • Customizing SDK method and parameter names
  • Adding examples and documentation
  • Configuring audiences and filtering

Configure overlays

To use overlays, add them to your generators.yml file:

generators.yml
1api:
2 specs:
3 - spec: proto/user_service.proto
4 overlays:
5 - overlay.yml
6 generators:
7 - name: fernapi/fern-typescript-node-sdk
8 version: 0.8.8

Overlay file structure

Overlay files use Protocol Buffer text format with Fern extensions:

overlay.yml
1# Add SDK method names to existing gRPC methods
2service UserService {
3 rpc CreateUser {
4 option (x_fern_sdk_method_name) = "create";
5 }
6
7 rpc GetUser {
8 option (x_fern_sdk_method_name) = "get";
9 }
10
11 rpc ListUsers {
12 option (x_fern_sdk_method_name) = "list";
13 option (x_fern_pagination) = '{
14 "cursor": "page_token",
15 "results": "users",
16 "next_cursor": "next_page_token"
17 }';
18 }
19}

Add method names

Override SDK method names for better developer experience:

overlay.yml
1service UserService {
2 rpc GetUserById {
3 option (x_fern_sdk_method_name) = "getUser";
4 }
5
6 rpc CreateNewUser {
7 option (x_fern_sdk_method_name) = "create";
8 }
9
10 rpc UpdateUserProfile {
11 option (x_fern_sdk_method_name) = "updateProfile";
12 }
13
14 rpc DeleteUserAccount {
15 option (x_fern_sdk_method_name) = "delete";
16 }
17}
18
19service AuthenticationService {
20 option (x_fern_sdk_service_name) = "auth";
21
22 rpc LoginUser {
23 option (x_fern_sdk_method_name) = "login";
24 }
25
26 rpc LogoutUser {
27 option (x_fern_sdk_method_name) = "logout";
28 }
29}

Add parameter names

Customize parameter names for better SDK ergonomics:

overlay.yml
1message CreateUserRequest {
2 string email_address {
3 option (x_fern_parameter_name) = "email";
4 }
5
6 string full_name {
7 option (x_fern_parameter_name) = "name";
8 }
9
10 int32 age_in_years {
11 option (x_fern_parameter_name) = "age";
12 }
13
14 UserPreferences user_preferences {
15 option (x_fern_parameter_name) = "preferences";
16 }
17}
18
19message User {
20 string user_id {
21 option (x_fern_parameter_name) = "id";
22 }
23
24 google.protobuf.Timestamp created_timestamp {
25 option (x_fern_parameter_name) = "createdAt";
26 }
27
28 google.protobuf.Timestamp updated_timestamp {
29 option (x_fern_parameter_name) = "updatedAt";
30 }
31}

Add examples

Enhance your specification with comprehensive examples:

overlay.yml
1service UserService {
2 rpc CreateUser {
3 option (x_fern_examples) = '{
4 "StandardUser": {
5 "description": "Create a regular user account",
6 "request": {
7 "email": "john@example.com",
8 "name": "John Doe",
9 "age": 30,
10 "preferences": {
11 "theme": "dark",
12 "notifications": true
13 }
14 },
15 "response": {
16 "id": "user_123",
17 "email": "john@example.com",
18 "name": "John Doe",
19 "created_at": "2024-01-15T10:30:00Z"
20 }
21 },
22 "AdminUser": {
23 "description": "Create an admin user with permissions",
24 "request": {
25 "email": "admin@example.com",
26 "name": "Admin User",
27 "role": "admin",
28 "permissions": ["read", "write", "delete"]
29 },
30 "response": {
31 "id": "user_456",
32 "email": "admin@example.com",
33 "name": "Admin User",
34 "role": "admin",
35 "created_at": "2024-01-15T10:30:00Z"
36 }
37 }
38 }';
39 }
40}

Filter with audiences

Add audience filtering to services and methods:

overlay.yml
1service UserService {
2 option (x_fern_audiences) = "public";
3
4 rpc GetUser {
5 option (x_fern_audiences) = "public";
6 }
7
8 rpc CreateUser {
9 option (x_fern_audiences) = "public";
10 }
11}
12
13service AdminService {
14 option (x_fern_audiences) = "admin";
15
16 rpc ListAllUsers {
17 option (x_fern_audiences) = "admin";
18 }
19
20 rpc DeleteUser {
21 option (x_fern_audiences) = "admin";
22 }
23}
24
25service DebugService {
26 option (x_fern_audiences) = "internal";
27
28 rpc GetSystemInfo {
29 option (x_fern_audiences) = "internal";
30 }
31}

Add error handling

Configure custom error handling for methods:

overlay.yml
1service UserService {
2 rpc CreateUser {
3 option (x_fern_error_handling) = '{
4 "ALREADY_EXISTS": {
5 "error_name": "UserAlreadyExistsError",
6 "user_friendly_message": "A user with this email already exists"
7 },
8 "INVALID_ARGUMENT": {
9 "error_name": "ValidationError",
10 "user_friendly_message": "Please check your input and try again"
11 },
12 "RESOURCE_EXHAUSTED": {
13 "error_name": "RateLimitError",
14 "retry_after_seconds": 60
15 }
16 }';
17 }
18
19 rpc ProcessPayment {
20 option (x_fern_retry) = '{
21 "max_attempts": 3,
22 "exponential_backoff": true,
23 "initial_delay_ms": 1000,
24 "max_delay_ms": 30000
25 }';
26 }
27}

Add documentation

Enhance descriptions and documentation:

overlay.yml
1service UserService {
2 option (x_fern_service_description) = "User management service for creating, updating, and managing user accounts with comprehensive authentication and profile management capabilities.";
3
4 rpc CreateUser {
5 option (x_fern_method_description) = "Create a new user account with email verification and automatic profile setup. Supports custom preferences and role assignment.";
6 }
7
8 rpc GetUser {
9 option (x_fern_method_description) = "Retrieve user information by ID with optional inclusion of profile data, preferences, and activity history.";
10 }
11
12 rpc UpdateUser {
13 option (x_fern_method_description) = "Update user profile information with field-level updates using Protocol Buffer field masks for efficient partial updates.";
14 }
15}

Configure timeouts and retries

Add timeout and retry configurations:

overlay.yml
1service UserService {
2 rpc GenerateUserReport {
3 option (x_fern_timeout) = '{
4 "seconds": 300,
5 "description": "Report generation can take up to 5 minutes for large datasets"
6 }';
7 }
8
9 rpc QuickUserLookup {
10 option (x_fern_timeout) = '{
11 "seconds": 5,
12 "description": "Quick lookup operations should complete within 5 seconds"
13 }';
14 }
15
16 rpc ImportUsers {
17 option (x_fern_retry) = '{
18 "max_attempts": 5,
19 "exponential_backoff": true,
20 "initial_delay_ms": 2000,
21 "max_delay_ms": 60000,
22 "retry_on_status": ["UNAVAILABLE", "DEADLINE_EXCEEDED", "INTERNAL"]
23 }';
24 }
25}

Streaming configurations

Configure streaming methods:

overlay.yml
1service UserStreamingService {
2 rpc StreamUserEvents {
3 option (x_fern_streaming) = '{
4 "type": "server_streaming",
5 "termination": "client_closes",
6 "description": "Real-time stream of user events with automatic reconnection"
7 }';
8 }
9
10 rpc UploadUserData {
11 option (x_fern_streaming) = '{
12 "type": "client_streaming",
13 "termination": "client_closes",
14 "max_message_size": "10MB"
15 }';
16 }
17
18 rpc ChatWithSupport {
19 option (x_fern_streaming) = '{
20 "type": "bidirectional_streaming",
21 "termination": "either_closes",
22 "heartbeat_interval": "30s"
23 }';
24 }
25}

Multiple overlays

You can apply multiple overlay files in sequence:

generators.yml
1api:
2 specs:
3 - spec: proto/user_service.proto
4 overlays:
5 - base-overlay.yml
6 - sdk-overlay.yml
7 - docs-overlay.yml
8 - examples-overlay.yml

Environment-specific overlays

Use different overlays for different environments:

generators.yml
1groups:
2 production:
3 audiences: [public]
4 specs:
5 - spec: proto/user_service.proto
6 overlays:
7 - production-overlay.yml
8 generators:
9 - name: fernapi/fern-typescript-node-sdk
10 version: 0.8.8
11 internal:
12 audiences: [admin, internal]
13 specs:
14 - spec: proto/user_service.proto
15 overlays:
16 - internal-overlay.yml
17 generators:
18 - name: fernapi/fern-typescript-node-sdk
19 version: 0.8.8

Field-level overlays

Apply overlays to specific message fields:

overlay.yml
1message UserPreferences {
2 map<string, string> notification_settings {
3 option (x_fern_parameter_name) = "notifications";
4 option (x_fern_field_description) = "User notification preferences with support for email, SMS, and push notifications";
5 }
6
7 map<string, bool> feature_flags {
8 option (x_fern_parameter_name) = "features";
9 option (x_fern_field_description) = "Feature flags controlling access to beta and experimental features";
10 }
11
12 string preferred_language {
13 option (x_fern_parameter_name) = "language";
14 option (x_fern_validation) = '{
15 "enum": ["en", "es", "fr", "de", "zh"],
16 "default": "en"
17 }';
18 }
19}

Validation overlays

Add validation rules to existing fields:

overlay.yml
1message CreateUserRequest {
2 string email {
3 option (x_fern_validation) = '{
4 "format": "email",
5 "required": true,
6 "description": "Must be a valid email address"
7 }';
8 }
9
10 string name {
11 option (x_fern_validation) = '{
12 "min_length": 1,
13 "max_length": 100,
14 "required": true,
15 "pattern": "^[a-zA-Z\\s]+$"
16 }';
17 }
18
19 int32 age {
20 option (x_fern_validation) = '{
21 "minimum": 0,
22 "maximum": 120,
23 "description": "Age in years"
24 }';
25 }
26}

Overlays are applied in order, allowing you to build up customizations incrementally while keeping your original Protocol Buffer files clean and focused on the core service definition.