Skip to content

feat: support x-fern-display-name on AsyncAPI operations#14848

Open
fern-support wants to merge 1 commit intomainfrom
devin/1775753576-asyncapi-operation-display-name
Open

feat: support x-fern-display-name on AsyncAPI operations#14848
fern-support wants to merge 1 commit intomainfrom
devin/1775753576-asyncapi-operation-display-name

Conversation

@fern-support
Copy link
Copy Markdown
Collaborator

Description

Adds support for the x-fern-display-name extension on AsyncAPI operations, allowing users to set custom display names for operations independently of the operation key. This is useful when operation keys must be globally unique (e.g., versioned endpoints like SendMessageV1) but the docs should show a friendlier name (e.g., Send Message).

Previously, x-fern-display-name only worked on channels. Operation display names were hardcoded to the operation key (v3) or "publish"/"subscribe" (v2).

Changes Made

  • Generalized DisplayNameExtension to accept operations (v2 publish/subscribe, v3 operations) in addition to channels, renaming channelnode
  • AsyncAPI v3 (asyncapi-to-ir): Read x-fern-display-name from each operation in ChannelConverter3_0, falling back to operationId
  • AsyncAPI v2 (asyncapi-to-ir): Read x-fern-display-name from publish/subscribe in ChannelConverter2_X, falling back to message type
  • AsyncAPI v3 (openapi-ir-parser): Extract displayName from operations in parseAsyncAPIV3 and pass through to WebsocketMessageSchema
  • AsyncAPI v2 (openapi-ir-parser): Extract displayName from publish/subscribe in parseAsyncAPIV2
  • Added displayName: optional<string> to WebsocketMessageSchema in OpenAPI IR (definition, API type, serialization)
  • Updated buildChannel.ts to forward displayNamedisplay-name in the Fern Definition output

Both parser code paths (newer asyncapi-to-ir and older openapi-ir-parser) are updated.

Testing

  • Unit tests added/updated
  • Lint passes (biome check)

Suggested reviewer checklist

  • Verify DisplayNameExtension type union correctly covers all operation types
  • Confirm auto-generated OpenAPI IR files (WebsocketMessageSchema.ts) are consistent with finalIr.yml definition change
  • Consider whether a seed test fixture would be valuable for regression coverage

Link to Devin session: https://app.devin.ai/sessions/3702d64e03ae4c63bec715eecfc0b3b3
Requested by: @cdonel707

Add support for the x-fern-display-name extension on AsyncAPI v3
operations and AsyncAPI v2 publish/subscribe operations. This allows
users to set custom display names for operations in docs independently
of the operation key, which is useful when operation keys must be
unique across versioned endpoints.

Co-Authored-By: Chris McDonnell <chris@buildwithfern.com>
@devin-ai-integration
Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Copy link
Copy Markdown

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

SDK Generation Benchmark Results

Comparing PR branch against latest nightly baseline on main (2026-04-09T04:46:50Z).

Full benchmark table (click to expand)
Generator Spec main (generator) main (E2E) PR (generator) Delta
csharp-sdk square 95s 138s 87s -8s (-8.4%)
go-sdk square 107s 134s 105s -2s (-1.9%)
java-sdk square 290s 346s 291s +1s (+0.3%)
php-sdk square 85s 119s 84s -1s (-1.2%)
python-sdk square 130s 166s 127s -3s (-2.3%)
ruby-sdk-v2 square 115s 153s 113s -2s (-1.7%)
rust-sdk square 93s 95s 102s +9s (+9.7%)
swift-sdk square 104s 448s 106s +2s (+1.9%)
ts-sdk square 98s 134s 96s -2s (-2.0%)

main (generator): generator-only time via --skip-scripts (includes Docker image build, container startup, IR parsing, and code generation — this is the same Docker-based flow customers use via fern generate). main (E2E): full customer-observable time including build/test scripts (nightly baseline, informational). Delta is computed against generator-only baseline.
⚠️ = generation exited with a non-zero exit code (timing may not reflect a successful run).
Baseline from nightly runs on main (latest: 2026-04-09T04:46:50Z). Trigger benchmark-baseline to refresh.

@devin-ai-integration
Copy link
Copy Markdown
Contributor

Local Testing Results

Built the CLI locally and ran write-definition against sample AsyncAPI v2 and v3 specs to verify x-fern-display-name on operations.

Test 1: AsyncAPI v3 — operations WITH x-fern-display-name (PASSED)

Input — operations with x-fern-display-name:

operations:
  SendPlantUpdateV1:
    x-fern-display-name: Send Plant Update
    action: send
    ...
  ReceivePlantStatusV1:
    x-fern-display-name: Receive Plant Status
    action: receive
    ...

Output — Fern Definition YAML:

channel:
  messages:
    plantStatus:
      body: PlantStatus
      display-name: Receive Plant Status
      origin: server
    plantUpdate:
      body: PlantUpdate
      display-name: Send Plant Update
      origin: client

display-name correctly extracted from v3 operation extensions.

Test 2: Backward Compatibility — no x-fern-display-name (PASSED)

Used existing fixture single-no-endpoint-async. Output contains no display-name field on messages — backward compatibility confirmed.

channel:
  messages:
    testChannel_sendMessage:
      body: string
      origin: client
  path: /test
Test 3: AsyncAPI v2 — publish/subscribe WITH x-fern-display-name (PASSED)

Input — v2 publish/subscribe with x-fern-display-name:

channels:
  /plants/updates:
    publish:
      x-fern-display-name: Send Plant Update
      ...
    subscribe:
      x-fern-display-name: Receive Plant Status
      ...

Output — Fern Definition YAML:

channel:
  messages:
    publish:
      body: PlantsUpdatesPublish
      display-name: Send Plant Update
      origin: client
    subscribe:
      body: PlantsUpdatesSubscribe
      display-name: Receive Plant Status
      origin: server

display-name correctly extracted from v2 publish/subscribe operation extensions.


Summary: All 3 tests passed. The feature works end-to-end for both AsyncAPI v2 and v3 through the write-definition path.

Devin session

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants