swag icon indicating copy to clipboard operation
swag copied to clipboard

OpenAPI 2: Generated model definition name contains package prefix

Open 07bluestopher opened this issue 3 years ago • 3 comments

Describe the bug OpenAPI 2 produced definition name for model contains package name.

To Reproduce Steps to reproduce the behavior:

  1. swag init
  2. Check produced yaml definitions

Expected behavior I would expect my definitions to not include the package as a prefix of the model name. For example, the produced model definition for my Account model is "models.Account". I would expect it to be Account without the "models." prefix.

Code Samples I annotate my API as:

// @Summary Get Account
// @Schemes
// @Description Get account data from session token
// @Tags Account
// @Accept json
// @Produce json
// @Success 200 {object} models.Account
// @Router /account [get]
func (h *AccountController) GetAccount(c *gin.Context) {

}

The models.Account struct comes from my model package, which is defined as (I use the validate required tag to prevent the procuded model properties as being 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" validate:"required"`
	Username    string   `json:"username" validate:"required"`
	Nick        string   `json:"nick"`
	Avatar      string   `json:"avatar" validate:"required"`
	Roles       []string `json:"roles" validate:"required"`
	GuildAvatar string   `json:"guildAvatar"`
	Rank        string   `json:"rank" validate:"required"`
}

Which produces this definition and name for the model:

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
      nick:
        type: string
      rank:
        type: string
      roles:
        items:
          type: string
        type: array
      username:
        type: string
    required:
    - avatar
    - id
    - rank
    - roles
    - username
    type: object

I am expecting to produce a definition with the model name not containing "models.". This is the expected format I am looking to produce:

definitions:
  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
      nick:
        type: string
      rank:
        type: string
      roles:
        items:
          type: string
        type: array
      username:
        type: string
    required:
    - avatar
    - id
    - rank
    - roles
    - username
    type: object

Your swag version swag version: 1.8.12

Your go version Go version: 1.19

Desktop (please complete the following information):

  • OS: Windows

Additional context Add any other context about the problem here.

07bluestopher avatar Apr 07 '23 17:04 07bluestopher

I solved my problem by adding an @name annotation to my type and updating my API to reference the new name.

For example, here is my struct now (Notice the @name annotation):

// 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" validate:"required"`
	Username    string   `json:"username" validate:"required"`
	Nick        string   `json:"nick"`
	Avatar      string   `json:"avatar" validate:"required"`
	Roles       []string `json:"roles" validate:"required"`
	GuildAvatar string   `json:"guildAvatar"`
	Rank        string   `json:"rank" validate:"required"`
} //@name Account

Here is the API definition updated to reference Account instead of models.Account:

// @Summary Get Account
// @Schemes
// @Description Get account data from session token
// @Tags Account
// @Accept json
// @Produce json
// @Success 200 {object} models.Account
// @Router /account [get]
func (h *AccountController) GetAccount(c *gin.Context) {

}

This results in a produced definition as:

definitions:
  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
      nick:
        type: string
      rank:
        type: string
      roles:
        items:
          type: string
        type: array
      username:
        type: string
    required:
    - avatar
    - id
    - rank
    - roles
    - username
    type: object

07bluestopher avatar Apr 07 '23 18:04 07bluestopher

I solved my problem by adding an @name annotation to my type and updating my API to reference the new name.

For example, here is my struct now (Notice the @name annotation):

// 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" validate:"required"`
	Username    string   `json:"username" validate:"required"`
	Nick        string   `json:"nick"`
	Avatar      string   `json:"avatar" validate:"required"`
	Roles       []string `json:"roles" validate:"required"`
	GuildAvatar string   `json:"guildAvatar"`
	Rank        string   `json:"rank" validate:"required"`
} //@name Account

Here is the API definition updated to reference Account instead of models.Account:

// @Summary Get Account
// @Schemes
// @Description Get account data from session token
// @Tags Account
// @Accept json
// @Produce json
// @Success 200 {object} models.Account
// @Router /account [get]
func (h *AccountController) GetAccount(c *gin.Context) {

}

This results in a produced definition as:

definitions:
  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
      nick:
        type: string
      rank:
        type: string
      roles:
        items:
          type: string
        type: array
      username:
        type: string
    required:
    - avatar
    - id
    - rank
    - roles
    - username
    type: object

I have resolved the problem in the same way.

ZanonEdoardo avatar May 17 '23 09:05 ZanonEdoardo

This method does not work when using the --v3.1 flag.

nikpivkin avatar Feb 10 '25 09:02 nikpivkin