Naming
Every Go name the generator writes comes from the same rules, so the same spec gives the same names on every run. When two names clash, the generator picks a winner the same way every time and reports each rename.
Turning a spec name into a Go name
| Spec name | Go name | Rule |
|---|---|---|
client_address, client-address, client.address |
ClientAddress |
Any character that is not a letter or a digit splits words, apart from the symbols below. |
fooBar, HTTPServer |
FooBar, HTTPServer |
A capital starts a word. An upper-case run ends before its last capital when a lower-case letter follows. |
v2api, 404NotFound |
V2API, N404NotFound |
Digits stay with the word before them. A letter after them starts a new word, unless the word starts with the digits: 1st stays one word. |
CLIENT_ADDRESS, SSN |
ClientAddress, Ssn |
Every word is written with one capital, unless it is an initialism. |
userId, urls, userIDs, id2, short_2url |
UserID, URLs, UserIDs, ID2, Short2URL |
Initialisms stay upper case, also with a plural s or digits before or after them. |
1st, 200 |
N1st, N200 |
A name that would start with a digit gets N in front. |
+1, -1, -created_at, @type |
Plus1, Minus1, MinusCreatedAt, AtType |
+ and @ become words anywhere, - only at the start. |
1.5, v1.2 |
N1Dot5, V1Dot2 |
A dot between two digits becomes Dot. |
$, >=, !=, _ |
Dollar, GreaterThanEqual, NotEqual, Underscore |
A name with no letters or digits spells out its symbols. |
naïve, Straße |
Naive, Strasse |
Latin letters with accents lose them. |
日本語Name, 名前 |
Name, X540D |
Other letters are dropped. When nothing is left, the name is X and the first character's code in hex. |
| empty string | Empty |
An enum value "" gives StatusEmpty. A property, parameter or header named "" gets no field, with a warning (name-empty). |
Unexported names
Names of function arguments and local variables follow the same rules, with the first word in
lower case: HTTPServer gives httpServer.
A Go keyword or predeclared name gets Val: type gives typeVal, string gives stringVal.
Initialisms
The default initialisms are API, ASCII, CPU, CSS, DNS, EOF, HTML, HTTP, HTTPS, ID, IP, JSON, OAS, RPC, SQL, SSH, TCP, TLS, TTL, UDP, URI, URL, UTF8, UUID and XML. Add your own in the config:
naming:
initialisms: [PSP, SSN]
An initialism matches a whole word in any case: Id, id and ID all give ID. It does not
match inside a word, so userid stays Userid. Digits in front do not stop it: with DS listed,
force_3ds_flow gives Force3DSFlow.
Names for types without a name
Schemas under components keep their own name. Everything else is named after where it sits.
| Origin | Name | Example |
|---|---|---|
| Inline object under a property | parent + property | OrderClientAddress |
| Inline array item | parent + Item |
OrderItem |
Inline additionalProperties value |
parent + Value |
LabelsValue |
| Inline union variant | parent + title, else discriminator value, else Option + position from 1 |
PaymentMethodCard, PaymentMethodOption2 |
| Request body | operation + RequestBody |
CreatePetRequestBody |
| Request body, one of several media types | operation + media type + RequestBody |
CreatePetJSONRequestBody |
| Response | operation + Response + status |
GetPetResponse200, GetPetResponse4XX, GetPetResponseDefault |
| Response, one of several media types | operation + media type + Response + status |
GetPetJSONResponse200 |
Frame of a streamed response (from itemSchema, or from the schema of text/event-stream or a line-delimited JSON type) |
operation + ResponseItem |
ListEventsResponseItem |
| Frame of a streamed response, when the operation has more than one inline | response + Item |
ListEventsResponse200Item, ListEventsNdjsonResponse200Item |
Item of a component or a request body that has itemSchema; the schema of a sequential request body |
parent + Item |
LinesItem, ChatRequestBodyItem |
| Path parameters | operation + PathParams |
GetPetPathParams |
| Query parameters | operation + Query |
GetPetQuery |
| Header parameters | operation + Headers |
GetPetHeaders |
| Cookie parameters | operation + Cookies |
GetPetCookies |
| Service method input | operation + ServiceRequestOptions |
GetPetServiceRequestOptions |
| Service method output | operation + ResponseData |
GetPetResponseData |
| Enum constant | type + value | StatusActive, LevelMinus1, StatusEmpty |
Media types in a name
Four media types have a fixed name:
| Media type | In a name |
|---|---|
application/json |
JSON |
application/x-www-form-urlencoded |
Form |
multipart/form-data |
Multipart |
text/plain |
Text |
Any other media type gives its subtype without an x- prefix. A wildcard subtype gives the type,
and */* gives Any.
| Media type | In a name |
|---|---|
application/problem+json |
ProblemJSON |
application/x-ndjson |
Ndjson |
image/* |
Image |
*/* |
Any |
Clashes
Two names clash when they are equal ignoring case. PetId and PetID clash. Names the generator
itself declares, such as NewRouter, are taken before anything from the spec.
Who gets the name
When several things want the same name, it goes to the first in this order:
- a name set with
x-go-nameorx-go-type-name - a schema under
components/schemas - anything else under
components - a type named after an operation
- an inline type
Within one group the spec order decides.
The others try a name that says where they come from, such as PetResponse for a response called
Pet. When that is taken too, they get the first free number from 2: PetResponse2,
PetResponse3.
Struct fields
A struct field clashes with the methods the generator puts on the struct.
| Struct | Names taken |
|---|---|
| every struct | Validate, MarshalJSON, UnmarshalJSON |
| one with additional properties | also Get, Set and the AdditionalProperties field |
A property called validate gives the field Validate2.
A getter (Get + field, see defaults) never renames a field. When a field
already has the getter's name, the getter is left out with a warning (name-clash).
Enums
Enum constants clash with every other name in the package.
An enum also holds the name of its values func, <Enum>Values. A constant or a type that wants
that name is renamed, so the value values of Status gives StatusValues2.
Operations
Operations become methods, so their names clash only with each other. An operation also holds the names of the other methods it gets:
| Name held | When |
|---|---|
<Op>Request |
on the client |
<Op>WithResponse |
with client.with-response |
<Op>Stream, <Op>StreamWithResponse |
with client.streaming, when the operation answers a 2xx as a stream |
<Op>Tool |
when the MCP tools keep the operation |
Webhooks get none of them.
So of getCert and getCertRequest, the second is renamed, whatever the spec order:
GetCertRequest2 in the service, the client and the tools. The MCP tool name stays
get_cert_request. With MCP, Register is taken.
Duplicate operationId
OpenAPI wants every operationId to be unique. One that an earlier operation already has is
renamed with a number, ListThings2. This is reported as a warning (operation-id-duplicate)
that names both operations.
Order of naming
Names are given in rounds. First every type named directly (components, operation types), then the types inside them, one level at a time.
An inline type is named after the final name of its parent. When Client is renamed to
ClientSchema, its inline address becomes ClientSchemaAddress.
Reports
Every rename is reported as a name-clash diagnostic with the spec location of the renamed item.
Losing a name set with x-go-name or x-go-type-name is a warning. Set one of them to choose a
name yourself.