Repository navigation
Idiomatic Go SDK output for imperfect vendor specs - #653
Merged
Merged
Conversation
daveshanley
marked this pull request as ready for review
October 7, 2026 16:03
daveshanley
force-pushed
the
claude/nifty-snyder-3d2f35
branch
from
October 7, 2026 16:05
8b827e9 to
088b3c1
Compare
A real-world vendor spec (OpenAPI 3.1, inline schemas, nullable in 3.1, a text/plain 401) failed to generate, and the output after working around the 401 was noisy: underscore type names, ID__2, "example value is defined" comments, raw HTML in parameter docs, and any/map[string]any for undescribed JSON. gosdk - Declared non-JSON error responses keep their raw body in APIError.Body instead of failing generation. - Types for a named operation derive from Resource+Method (PeopleMatchParams, PeopleMatchResponse, PeopleMatchBadRequest). - Inline payload types take their property name when free (Person, Organization, EmploymentHistoryItem); component children stay qualified. - Parameter docs render as wrapped godoc above each field. - Defaults: idiomatic names, json.RawMessage for undescribed JSON, enum constants (all overridable through Options.Models). - Error cases are grouped, sorted, and ordered exact > range > default; response-only models use single pointers; the client declares only the helpers its operations call. generator/golang - NameStyleIdiomatic, WithInlineRoots, WithReservedTypeNames, WithUntypedAsRawMessage, WithDecodeOnlyRoots, WithFallbackDescriptions, FieldNames, NewIdiomaticNameRegistry, DiagnosticNullableKeyword. - Comments: descriptions rendered whole and wrapped; noise notes removed. - Fixes: properties beside allOf were dropped; unused nested map and tuple declarations removed; plural initialisms and digit word breaks. Standalone model generator naming defaults are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
daveshanley
force-pushed
the
claude/nifty-snyder-3d2f35
branch
from
October 7, 2026 16:07
088b3c1 to
593584c
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #653 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 308 309 +1
Lines 38781 39208 +427
==========================================
+ Hits 38781 39208 +427
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A real-world vendor OpenAPI 3.1 spec failed to generate. It uses mostly inline schemas,
nullableinside 3.1, and declares atext/plain401. After working around the 401, the output had underscore type names,ID__2, 151 "example value is defined in the OpenAPI schema" comments, raw HTML in parameter docs, andany/map[string]anyfor undescribed JSON. This change makes such specs generate clean, idiomatic Go while staying contract-faithful.gosdk
text/plain) keeps its raw body inAPIError.Body; it no longer fails generation. Non-JSON success bodies are still refused.PeopleMatchParams,PeopleMatchResponse,PeopleMatchBadRequest,PeopleMatchTooManyRequests. Unnamed operations still use the operationId.Person,Organization,EmploymentHistoryItem,ContactEmail). Inline types inside components stay qualified by their parent (AccountStatus).4XXdeclared ahead of404caught the 404.*Tinstead of**T. The client declares only the unexported helpers its operations call.Options.Models: idiomatic names,json.RawMessagefor undescribed JSON, and enum constants.sdk.Operation.Namedrecords whether the caller chose the method name.generator/golang
NameStyleIdiomatic,WithNameStyle,WithInlineRoots,WithReservedTypeNames,WithUntypedAsRawMessage,WithDecodeOnlyRoots,WithFallbackDescriptions,FieldNames,NewIdiomaticNameRegistry,NameRegistry.ResolveFirst/ClaimFirst, andDiagnosticNullableKeyword. Anullable: truein a 3.1 document is honoured and reported.Deprecated:paragraph.LabelIDs), digit word breaks (Base64Encoded),MD5/SHA256. Fields_idandidbecomeUnderscoreIDandID.propertieswritten besideallOfwere silently dropped. Unused nested map and tuple declarations were emitted. An inline schema reached twice (for example through a YAML anchor) got two type names but only one declaration.generator/internal/gocommentturns description text into Go comments.generator/typescript
allOfsiblings, because the shared IR now carries them. Output is identical for valid schemas. A sibling property that cannot be built now renders asunknownwith a diagnostic, like any other unbuildable property.Reviewer notes
Parent_Childand__Nnaming by default. Only gosdk opts into the idiomatic style.name_collisions_idiomatic.golden.go, plus three SDK goldens generated from a people-match fixture. The fixture is extracted from the public vendor spec, with its source cited in its header; only the responseexamplesblocks are removed.go test ./...passes.Playing Field impact (regenerated in a scratch copy)
api.gen.tsoutput is byte-identical.map[string]anyfields are gone, and 55 enums gain constants.ListAccountsParams→AccountsListRawParams,ListAccountsStatus200responseUnion→AccountsListRawResponseUnion,CreateAccountParams→AccountsCreateParams,CreateAccountRequest→AccountsCreateRequest,GetAccountParams→AccountsGetParams. With those renames, PF's SDK tests pass under-race.🤖 Generated with Claude Code