Types
Type naming
Speakeasy tries to name your types using the shortest name possible, this is done by trying to deduce a name from its surrounding context.
Types defined via components will generally fare best when it comes to the name chosen for them. Where possible, we use the component's key name as the type name.
For example given the following schema:
components: schemas: User: type: object properties: id: type: string name: type: string
The type name for the User
schema will be User
where possible unless it potentially conflicts with another type in the same namespace then name resolution will kick in and the earliest encountered type will be named User
and the later encountered types will have various context used to determine relevant prefixes/suffixes to add to the types to avoid conflicts.
Where a component name is unavailable for example when the type is defined inline in a schema, request, response, parameter etc
We will start using other context to determine the name of the type in the following order:
x-speakeasy-name-override
extension value in the schematitle
property in the schema$anchor
property in the schema- any other surrounding context of the schema
The types that are named this way are objects
that become classes, integer
and string
types that have enum
values defined in the schema or oneOf
/anyOf
schemas that become union types.
Inline schemas like in the below example will generally run the risk of having names chosen that will conflict with other types more often and will generally start having context prefixes/suffixes added to the type names until the type no longer conflicts with another type.
paths: /users: get: operationId: getUsers responses: '200': content: application/json: schema: type: array items: type: object # inline schema that will be named based on surrounding context title: User properties: id: type: string name: type: string /user: get: operationId: getUser responses: '200': content: application/json: schema: type: object # inline scheme that will be named based on surrounding context title: User properties: id: type: string name: type: string
In the above example both inline schemas will attempt to be named User
but will conflict with one another (we don't do any inference to try and understand if these are the same type) the second schema will have a context prefix added to it to avoid a conflict with the first schema.
Some of the context prefixes/suffixes that can be added to the type names are:
- Reference Type
- Reference Name
- Property Name
- Operation Name
- Tag Name
- Request
- Response
- Position in
oneOf
/anyOf
schema - etc
When we run out of context to name the type we will start using numbers to suffix the type name.
To avoid unexpected type names and ensure you get the names you expect the recommendation is to use unique component names for your schemas whereever possible.
Input/Output Models
Speakeasy will generate separate input and output models for schemas that are used in both request and response bodies and define readOnly
and writeOnly
flags on their properties.
For example given the following schema:
paths: /drinks/{id}: post: operationId: updateDrink parameters: - name: id in: path required: true schema: type: string requestBody: content: application/json: schema: $ref: '#/components/schemas/Drink' responses: '200': content: application/json: schema: $ref: '#/components/schemas/Drink'components: schemas: Drink: type: object properties: id: type: string readOnly: true stockUpdate: type: integer writeOnly: true name: type: string category: type: string stock: type: integer readOnly: true
The Drink
component is used both as a request body and response body schema, but it is using fields that can only be set when updating the drink and read when getting the returned drink.
In this case Speakeasy will generate two models DrinkInput
and DrinkOutput
._createMdxContent
DrinkInput
will have the following properties:
- stockUpdate
- name
- category
DrinkOutput
will have the following properties:
- id
- name
- category
- stock
In the case where a schema has only readOnly
flags and no writeOnly
flags or vice versa, Speakeasy will generate two models still if used in both request and response bodies, but the Input
/Output
schema will be added only to the relevant models based on the flags.
The Input
/Output
suffixes can be reconfigured using the inputModelSuffix
and outputModelSuffix
options in the gen.yaml
file. See the gen.yaml reference for more infomation.
Const / Default Handling
If a schema has a const
or default
value defined on it, Speakeasy will generate code to handle these where ever possible.
Const
Consts allow you to specify a value that must be transmitted to the server and is always expected to be received from the server.
For example:
components: schemas: Drink: type: object properties: type: type: string const: 'drink'
The type
property has a const
value of drink
the SDK will be generated with this field not being available to set as the value drink
will always be transmitted. Then const getters will be generated for accessing the value if required.
Default
Defaults allow you to specify a value to be transmitted to the server if none is provided by the end user.
For example:
components: schemas: Drink: type: object properties: category: type: string default: 'spirits' required: - category
The category
property has a default of spirits
even though this field is marked required
the SDK will be generated with this field being optional and the value spirits
will be transmitted if no other value is provided by the end user.
Examples
If an example
or examples
field is provided on the type, Speakeasy will use the values (if valid for the defined schema) to populate usage snippets in the generated SDKs.
If more than one example is provided in the examples
field, then a random example will be chosen.