Skip to content

Derive request/response type names from method+path when operationId is missing #181

@HavenDV

Description

@HavenDV

Problem

When an OpenAPI spec has inline request/response schemas and no operationId, AutoSDK generates generic sequential names like Request, Request2, Request3, ... Request45. These names are:

  1. Unstable — adding/removing/reordering endpoints in the spec shifts all numeric suffixes, breaking downstream code
  2. Unreadable — developers see new Request45 { Q = "..." } instead of new CreateQuicksearchRequest { Q = "..." }

This is a recurring problem. Every time the HuggingFace spec auto-updates (every 3 hours via CI), type numbers shift and integration tests break (e.g. HuggingFace#124).

Root Cause

The naming logic in ModelNameGenerator.cs resolves inline schema names via Hint:

  • Hint.Request{OperationId}Request
  • Hint.Response{OperationId}Response

When operationId is absent, it falls back to the bare hint name (Request), and collision resolution appends numeric suffixes (Request2, Request3, ...).

Affected SDKs

SDK Inline schemas operationIds Result
HuggingFace 73/73 (100%) 0/191 Request2..Request45, Response2..Response97
Fal Many Missing Similar RequestN/ResponseN pattern
Langfuse Many Missing Similar pattern
Roboflow Many Missing Similar pattern

Any spec without operationId and with inline schemas is affected.

Proposed Solution

When operationId is missing and the schema is an inline request/response body, derive a name from HTTP method + path (the same MethodAndPath convention already used for method naming fallback):

POST /api/quicksearch → CreateQuicksearchRequest
GET /api/models/{repo_id} → GetModelsRequest / GetModelsResponse  
DELETE /api/repos/{repo_type}/{repo_id} → DeleteReposRequest

Algorithm

  1. When generating a name for an inline request/response schema:

    • If operationId exists → use it (current behavior, no change)
    • If schema has title → use it (current behavior, no change)
    • NEW: If neither exists → derive from HTTP method + path:
      • Strip path parameters: /api/models/{repo_id}/api/models
      • Convert to PascalCase: api/modelsApiModels
      • Prepend HTTP method: GETGet, POSTCreate, PUTUpdate, DELETEDelete, PATCHPatch
      • Append hint: Request or Response
      • Result: GetApiModelsResponse, CreateApiQuicksearchRequest
  2. This mirrors the existing MethodAndPath convention in MethodNamingConvention.cs but applied to type names.

Benefits

  • Stable — type names derived from path structure, which rarely changes even when endpoints are added/removed
  • ReadableCreateQuicksearchRequest vs Request45
  • Backward-compatible — only affects specs without operationId; specs with operationId are unchanged
  • Consistent — method names and type names follow the same derivation logic

Current Naming Code Reference

  • Collision resolution: ModelNameGenerator.cs lines 134-158 (ResolveCollisions())
  • Hint enum: Hint.csRequest, Response, Parameter
  • Method naming fallback: MethodNamingConvention.csMethodAndPath convention
  • Extension naming: x-fern-type-name support already exists in ModelNameGenerator.cs lines 73-80

Alternative Considered

Spec-fixing in generate.sh — injecting operationId via jq/yq before running AutoSDK. This works per-SDK but doesn't solve the problem globally and adds maintenance burden to every affected SDK.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions