New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for deep models #39

Closed
Sayujya opened this Issue Feb 1, 2018 · 13 comments

Comments

Projects
None yet
5 participants
@Sayujya

Sayujya commented Feb 1, 2018

Is there a way to get deep models working? Right now if I have a struct inside another struct, it doesn't recognize the top struct. Similarly bool (type bool) isn't recognized either.

@easonlin404 easonlin404 added the feature label Feb 2, 2018

@easonlin404

This comment has been minimized.

Show comment
Hide comment
@easonlin404

easonlin404 Feb 3, 2018

Member

@Sayujya you mean Nested structs (a struct inside another struct) or or Promoted fields ?

Nested structs:

type Person struct {  
    name string
    age int
    address Address
}

Promoted fields:

type Address struct {  
    city, state string
}
type Person struct {  
    name string
    age  int
    Address
}

Can you post your example?

Member

easonlin404 commented Feb 3, 2018

@Sayujya you mean Nested structs (a struct inside another struct) or or Promoted fields ?

Nested structs:

type Person struct {  
    name string
    age int
    address Address
}

Promoted fields:

type Address struct {  
    city, state string
}
type Person struct {  
    name string
    age  int
    Address
}

Can you post your example?

@easonlin404 easonlin404 added question and removed feature labels Feb 3, 2018

@easonlin404

This comment has been minimized.

Show comment
Hide comment
@easonlin404

easonlin404 Feb 4, 2018

Member

@Sayujya we add support for anonymous fields(promoted fields).#40

Member

easonlin404 commented Feb 4, 2018

@Sayujya we add support for anonymous fields(promoted fields).#40

@Sayujya

This comment has been minimized.

Show comment
Hide comment
@Sayujya

Sayujya Feb 5, 2018

How do you specify that? I just get this

{ 
  "Application": [ 
    null 
  ], 
  "Count": 0, 
  "Users": "Unknown Type: Users", 
  "Start": 0 
}
type AllocationGroup struct {
	Nodes    int
	Start	    int
	Pagination    Pagination
	Allocations[]    Allocation
}

type User struct { 
    name string 
    licenses int 
}

Sayujya commented Feb 5, 2018

How do you specify that? I just get this

{ 
  "Application": [ 
    null 
  ], 
  "Count": 0, 
  "Users": "Unknown Type: Users", 
  "Start": 0 
}
type AllocationGroup struct {
	Nodes    int
	Start	    int
	Pagination    Pagination
	Allocations[]    Allocation
}

type User struct { 
    name string 
    licenses int 
}
@easonlin404

This comment has been minimized.

Show comment
Hide comment
@easonlin404

easonlin404 Feb 15, 2018

Member

@Sayujya where is your type User declared ?

Member

easonlin404 commented Feb 15, 2018

@Sayujya where is your type User declared ?

@nadilas

This comment has been minimized.

Show comment
Hide comment
@nadilas

nadilas Feb 16, 2018

Contributor

@Sayujya don't you mean like:


type User struct { 
    name string 
    licenses int 
}

type A struct {
    Application []Application
    Count          int
    Users          []User
    Start            int
}

I'm facing a similar issue, where the type declared above its usage doesn't get recognized.

Contributor

nadilas commented Feb 16, 2018

@Sayujya don't you mean like:


type User struct { 
    name string 
    licenses int 
}

type A struct {
    Application []Application
    Count          int
    Users          []User
    Start            int
}

I'm facing a similar issue, where the type declared above its usage doesn't get recognized.

@easonlin404

This comment has been minimized.

Show comment
Hide comment
@easonlin404

easonlin404 Feb 17, 2018

Member

@nadilas can you post your declarative comments? I can't reproduce this issue.

Member

easonlin404 commented Feb 17, 2018

@nadilas can you post your declarative comments? I can't reproduce this issue.

@nadilas

This comment has been minimized.

Show comment
Hide comment
@nadilas

nadilas Feb 17, 2018

Contributor

Sure:

// @title API
// @version 1.0
// @description fdsfds
// @termsOfService asfsadf

// @contact.name API Support
// @contact.url dsgdfsg
// @contact.email fdssgfdsfd

// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html

// @host localhost
// @BasePath /v1
func main() { }

// @Summary fdsgfdsgfd
// @Description dfsgdfsgfd
// @ID get-all-tags
// @Accept  json
// @Produce  json
// @Param   some_id     path    int     true        "Some ID"
// @Success 200 {array} models.Tag
// @Failure 400 {object} models.APIError "ID is required"
// @Failure 404 {object} models.APIError "Can not find ID"
// @Router /v1/tags [get]
func GetTags(c *gin.Context) {}

type TagTemplate struct {
	ID         string
	TagId      string
	RemotePath string
	HtmlData   string
}

type Tag struct {
	ID            string
	Name          string
	Template      TagTemplate
	LabelType     LabelType
}

And the result:

200: 
[
  {
    "ID": "string",
    "LabelSerialNr": "string",
    "LabelType": "Unknown Type: LabelType",
    "Template": "Unknown Type: TagTemplate"
  }
]
Contributor

nadilas commented Feb 17, 2018

Sure:

// @title API
// @version 1.0
// @description fdsfds
// @termsOfService asfsadf

// @contact.name API Support
// @contact.url dsgdfsg
// @contact.email fdssgfdsfd

// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html

// @host localhost
// @BasePath /v1
func main() { }

// @Summary fdsgfdsgfd
// @Description dfsgdfsgfd
// @ID get-all-tags
// @Accept  json
// @Produce  json
// @Param   some_id     path    int     true        "Some ID"
// @Success 200 {array} models.Tag
// @Failure 400 {object} models.APIError "ID is required"
// @Failure 404 {object} models.APIError "Can not find ID"
// @Router /v1/tags [get]
func GetTags(c *gin.Context) {}

type TagTemplate struct {
	ID         string
	TagId      string
	RemotePath string
	HtmlData   string
}

type Tag struct {
	ID            string
	Name          string
	Template      TagTemplate
	LabelType     LabelType
}

And the result:

200: 
[
  {
    "ID": "string",
    "LabelSerialNr": "string",
    "LabelType": "Unknown Type: LabelType",
    "Template": "Unknown Type: TagTemplate"
  }
]
@easonlin404

This comment has been minimized.

Show comment
Hide comment
@easonlin404

easonlin404 Feb 17, 2018

Member

@nadilas I have created https://github.com/easonlin404/swag-issue using above declarative comments. Can you help to figure out?

Member

easonlin404 commented Feb 17, 2018

@nadilas I have created https://github.com/easonlin404/swag-issue using above declarative comments. Can you help to figure out?

@nadilas

This comment has been minimized.

Show comment
Hide comment
@nadilas

nadilas Feb 18, 2018

Contributor

@easonlin404 so I guess I found the issue. In the parser.go:186 you range over the types which have been registered in any route, but not their properties. This means, you don't get the depth, but only the directly referenced classes of the api.
I would solve it by adding a recursive check in parser.go:194 to generate the definitions of the types being used in the referenced model. (see pull request #42)

Problems I encountered:

  1. the package of the nested type must be the same as the owning type -- otherwise exception during parsing. Cross-package model nesting doesn't work
type Tag struct {
	ID            string
	Name          string
	Template      TagTemplate
	LabelType     LabelType
	Label2Type	  models2.Label2Type // doesn't work
}
panic: not supported 'astSelectorExpr' yet.

goroutine 1 [running]:
github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag.getPropertyName(0xc4203cab40, 0x0, 0x0)
	/workspace/go/src/github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag/property.go:25 +0x7f8
github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag.(*Parser).parseField(0xc420114400, 0xc4203cab40, 0x0, 0x0, 0x0, 0x0)
	/workspace/go/src/github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag/parser.go:285 +0x53
github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag.(*Parser).parseTypeSpec(0xc420114400, 0xc4203c04c8, 0x6, 0xc4201ad140, 0xc420396f90)
	/workspace/go/src/github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag/parser.go:253 +0x2a7
github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag.(*Parser).ParseDefinition(0xc420114400, 0xc4203c04c8, 0x6, 0xc4201ad140, 0xc42042adf4, 0x3)
	/workspace/go/src/github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag/parser.go:223 +0x311
github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag.(*Parser).ParseDefinitions(0xc420114400)
	/workspace/go/src/github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag/parser.go:194 +0x18d
  1. getting the models to be generated didn't resolve the referencing issue on the "Example Value | Model" section. Turns out swagger needs to know where to look for them ($ref was missing in the definitions section)

That's it. Models from the same package now get resolved.
Limitation:

  • Array of structs still not supported
  • Cross-package models are causing the exception above
Contributor

nadilas commented Feb 18, 2018

@easonlin404 so I guess I found the issue. In the parser.go:186 you range over the types which have been registered in any route, but not their properties. This means, you don't get the depth, but only the directly referenced classes of the api.
I would solve it by adding a recursive check in parser.go:194 to generate the definitions of the types being used in the referenced model. (see pull request #42)

Problems I encountered:

  1. the package of the nested type must be the same as the owning type -- otherwise exception during parsing. Cross-package model nesting doesn't work
type Tag struct {
	ID            string
	Name          string
	Template      TagTemplate
	LabelType     LabelType
	Label2Type	  models2.Label2Type // doesn't work
}
panic: not supported 'astSelectorExpr' yet.

goroutine 1 [running]:
github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag.getPropertyName(0xc4203cab40, 0x0, 0x0)
	/workspace/go/src/github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag/property.go:25 +0x7f8
github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag.(*Parser).parseField(0xc420114400, 0xc4203cab40, 0x0, 0x0, 0x0, 0x0)
	/workspace/go/src/github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag/parser.go:285 +0x53
github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag.(*Parser).parseTypeSpec(0xc420114400, 0xc4203c04c8, 0x6, 0xc4201ad140, 0xc420396f90)
	/workspace/go/src/github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag/parser.go:253 +0x2a7
github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag.(*Parser).ParseDefinition(0xc420114400, 0xc4203c04c8, 0x6, 0xc4201ad140, 0xc42042adf4, 0x3)
	/workspace/go/src/github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag/parser.go:223 +0x311
github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag.(*Parser).ParseDefinitions(0xc420114400)
	/workspace/go/src/github.com/easonlin404/swag-issue/vendor/github.com/swaggo/swag/parser.go:194 +0x18d
  1. getting the models to be generated didn't resolve the referencing issue on the "Example Value | Model" section. Turns out swagger needs to know where to look for them ($ref was missing in the definitions section)

That's it. Models from the same package now get resolved.
Limitation:

  • Array of structs still not supported
  • Cross-package models are causing the exception above
@easonlin404

This comment has been minimized.

Show comment
Hide comment
@easonlin404

easonlin404 Feb 19, 2018

Member

@nadilas thank you sorted out the problem and to add supported for cross-package models.
I will add 'Limitation' section to get better understand how to use it. Thanks your contribution. 💯

Member

easonlin404 commented Feb 19, 2018

@nadilas thank you sorted out the problem and to add supported for cross-package models.
I will add 'Limitation' section to get better understand how to use it. Thanks your contribution. 💯

@easonlin404

This comment has been minimized.

Show comment
Hide comment
@easonlin404

easonlin404 Feb 19, 2018

Member

fix via #42

Member

easonlin404 commented Feb 19, 2018

fix via #42

@hotarufk

This comment has been minimized.

Show comment
Hide comment
@hotarufk

hotarufk May 30, 2018

@easonlin404 how about case with nested struct ?
here is my struct :

type Address struct {
	City  string `json:"city,omitempty"`
	State string `json:"state,omitempty"`
}

// The person Type (more like an object)
type Person struct {
	ID        string   `json:"id,omitempty"`
	Firstname string   `json:"firstname,omitempty"`
	Lastname  string   `json:"lastname,omitempty"`
	Address   *Address `json:"address,omitempty"`
}

when i tried to use swag init command, i get this error :
image

hotarufk commented May 30, 2018

@easonlin404 how about case with nested struct ?
here is my struct :

type Address struct {
	City  string `json:"city,omitempty"`
	State string `json:"state,omitempty"`
}

// The person Type (more like an object)
type Person struct {
	ID        string   `json:"id,omitempty"`
	Firstname string   `json:"firstname,omitempty"`
	Lastname  string   `json:"lastname,omitempty"`
	Address   *Address `json:"address,omitempty"`
}

when i tried to use swag init command, i get this error :
image

@pei0804

This comment has been minimized.

Show comment
Hide comment
@pei0804

pei0804 Jul 22, 2018

Member

I fix.
#171

Member

pei0804 commented Jul 22, 2018

I fix.
#171

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment