OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.76k stars 6.57k forks source link

[BUG] openapi-generator typescript-axios generated model properties optional #15152

Open OSRSBlue opened 1 year ago

OSRSBlue commented 1 year ago

Bug Report Checklist

Description

When I generate a typescript-axios client from my APIs written in GoLang all of the models properties are optional. I would expect all the fields to be non optional unless specified.

openapi-generator version

Library: @openapitools/openapi-generator-cli: 2.5.2

OpenAPI declaration file content or url

GoLang Model

// Account model info
// @Description User account information
// @Description with user id, username, nickname, avatar, roles, guild avatar, and rank
type Account struct {
    ID          string   `json:"id"`
    Username    string   `json:"username"`
    Nick        string   `json:"nick"`
    Avatar      string   `json:"avatar"`
    Roles       []string `json:"roles"`
    GuildAvatar string   `json:"guildAvatar"`
    Rank        string   `json:"rank"`
}

Generated swag model from yaml file:

definitions:
  models.Account:
    description: User account information with user id, username, nickname, avatar,
      roles, guild avatar, and rank
    properties:
      avatar:
        type: string
      guildAvatar:
        type: string
      id:
        type: string
        x-nullable: "false"
      nick:
        type: string
      rank:
        type: string
      roles:
        items:
          type: string
        type: array
      username:
        type: string
    type: object

typescript-axios generated model from yaml file definition:

/**
 * User account information with user id, username, nickname, avatar, roles, guild avatar, and rank
 * @export
 * @interface ModelsAccount
 */
export interface ModelsAccount {
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'avatar'?: string;
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'guildAvatar'?: string;
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'id'?: string | null;
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'nick'?: string;
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'rank'?: string;
    /**
     * 
     * @type {Array<string>}
     * @memberof ModelsAccount
     */
    'roles'?: Array<string>;
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'username'?: string;
}
Generation Details

Building a typescript axios client using the command: openapi-generator-cli generate -i specFile -g typescript-axios -o outputDir -p packageName

results in all my produced models from my GoLang swag generated definition to be optional. I would expect them to not be optional unless specified.

Steps to reproduce
  1. Build API Spec with user defined Golang struct.
  2. Build an typescript axios client via: openapi-generator-cli generate -i specFile -g typescript-axios -o outputDir -p packageName
  3. Check produced models to verify all the properties are all optioanl (? next to the property name)
Suggest a fix

I may be describing my models incorrectly, so this could just be user error. If this is a feature ask I would think that being able to set a golang tag on properties for if they are nullable or not to avoid having all option properties in the generated typescript-axios client models.

For example, you have this GoLang struct, which produces that yaml and typescript model to have all fields being non optional, but the current behavior is to have all the fields as optional. I would expect the generated model to match my last example where the fields are not optional.

// Account model info
// @Description User account information
// @Description with user id, username, nickname, avatar, roles, guild avatar, and rank
type Account struct {
    ID          string   `json:"id"`
    Username    string   `json:"username"`
    Nick        string   `json:"nick"`
    Avatar      string   `json:"avatar"`
    Roles       []string `json:"roles"`
    GuildAvatar string   `json:"guildAvatar"`
    Rank        string   `json:"rank"`
}
definitions:
  models.Account:
    description: User account information with user id, username, nickname, avatar,
      roles, guild avatar, and rank
    properties:
      avatar:
        type: string
      guildAvatar:
        type: string
      id:
        type: string
        x-nullable: "false"
      nick:
        type: string
      rank:
        type: string
      roles:
        items:
          type: string
        type: array
      username:
        type: string
    type: object

typescript-axios generated model from yaml file definition:

/**
 * User account information with user id, username, nickname, avatar, roles, guild avatar, and rank
 * @export
 * @interface ModelsAccount
 */
export interface ModelsAccount {
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'avatar'?: string;
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'guildAvatar'?: string;
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'id'?: string | null;
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'nick'?: string;
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'rank'?: string;
    /**
     * 
     * @type {Array<string>}
     * @memberof ModelsAccount
     */
    'roles'?: Array<string>;
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'username'?: string;
}

This is my expected typescript-axios generated model from yaml file definition (All the properties are not optional):

/**
 * User account information with user id, username, nickname, avatar, roles, guild avatar, and rank
 * @export
 * @interface ModelsAccount
 */
export interface ModelsAccount {
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'avatar': string;
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'guildAvatar': string;
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'id': string;
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'nick': string;
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'rank': string;
    /**
     * 
     * @type {Array<string>}
     * @memberof ModelsAccount
     */
    'roles': Array<string>;
    /**
     * 
     * @type {string}
     * @memberof ModelsAccount
     */
    'username': string;
}
gabrielgrijincu commented 10 months ago

Also happens for me too. Would love a response from the team. ❤️

alexDrinkwater commented 6 months ago

If you don't want the properties to be optional you need to add them to the required list. e.g.

"myObj": {
  "properties": {
    "name": {
      "type": "string",
      "title": "Name"
    },
    "description": {
      "type": "string",
      "title": "Description"
    }
  },
  "type": "object",
  "required": [
    "name",
    "description"
  ],
  "title": "MyObj"
},