diff --git a/parser.go b/parser.go index f7c5612db..e43e1506b 100644 --- a/parser.go +++ b/parser.go @@ -1176,6 +1176,11 @@ func (parser *Parser) parseField(pkgName string, field *ast.Field) (*structField return &structField{name: ""}, nil } + // Skip non-exported fields. + if !ast.IsExported(field.Names[0].Name) { + return &structField{name: ""}, nil + } + structField := &structField{ name: field.Names[0].Name, schemaType: prop.SchemaType, diff --git a/parser_test.go b/parser_test.go index a06146712..7baa835c0 100644 --- a/parser_test.go +++ b/parser_test.go @@ -1947,6 +1947,81 @@ func TestParseStructComment(t *testing.T) { assert.Equal(t, expected, string(b)) } +func TestParseNonExportedJSONFields(t *testing.T) { + expected := `{ + "swagger": "2.0", + "info": { + "description": "This is a sample server.", + "title": "Swagger Example API", + "contact": {}, + "license": {}, + "version": "1.0" + }, + "host": "localhost:4000", + "basePath": "/api", + "paths": { + "/so-something": { + "get": { + "description": "Does something, but internal (non-exported) fields inside a struct won't be marshaled into JSON", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "summary": "Call DoSomething", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + } + } + } + } + }, + "definitions": { + "main.MyStruct": { + "type": "object", + "properties": { + "data": { + "description": "Post data", + "type": "object", + "properties": { + "name": { + "description": "Post tag", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "id": { + "type": "integer", + "format": "int64", + "example": 1 + }, + "name": { + "description": "Post name", + "type": "string", + "example": "poti" + } + } + } + } +}` + + searchDir := "testdata/non_exported_json_fields" + mainAPIFile := "main.go" + p := New() + err := p.ParseAPI(searchDir, mainAPIFile) + assert.NoError(t, err) + b, _ := json.MarshalIndent(p.swagger, "", " ") + assert.Equal(t, expected, string(b)) +} + func TestParsePetApi(t *testing.T) { expected := `{ "schemes": [ diff --git a/testdata/json_field_string/main.go b/testdata/json_field_string/main.go new file mode 100644 index 000000000..04515dccb --- /dev/null +++ b/testdata/json_field_string/main.go @@ -0,0 +1,39 @@ +package main + +import ( + "github.com/gin-gonic/gin" +) + +type MyStruct struct { + ID int `json:"id" example:"1" format:"int64"` + // Post name + Name string `json:"name" example:"poti"` + // Post data + Data struct { + // Post tag + Tag []string `json:"name"` + } `json:"data"` + // Integer represented by a string + MyInt int `json:"myint,string"` +} + +// @Summary Call DoSomething +// @Description Does something, but internal (non-exported) fields inside a struct won't be marshaled into JSON +// @Accept json +// @Produce json +// @Success 200 {string} MyStruct +// @Router /so-something [get] +func DoSomething(c *gin.Context) { + //write your code +} + +// @title Swagger Example API +// @version 1.0 +// @description This is a sample server. +// @host localhost:4000 +// @basePath /api +func main() { + r := gin.New() + r.GET("/do-something", api.DoSomething) + r.Run() +} diff --git a/testdata/non_exported_json_fields/main.go b/testdata/non_exported_json_fields/main.go new file mode 100644 index 000000000..ed641c38d --- /dev/null +++ b/testdata/non_exported_json_fields/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "github.com/gin-gonic/gin" +) + +type MyStruct struct { + ID int `json:"id" example:"1" format:"int64"` + // Post name + Name string `json:"name" example:"poti"` + // Post data + Data struct { + // Post tag + Tag []string `json:"name"` + } `json:"data"` + // not-exported variable, for internal use only, not marshaled + internal1 string + internal2 int + internal3 bool + internal4 struct { + NestedInternal string + } +} + +// @Summary Call DoSomething +// @Description Does something, but internal (non-exported) fields inside a struct won't be marshaled into JSON +// @Accept json +// @Produce json +// @Success 200 {string} MyStruct +// @Router /so-something [get] +func DoSomething(c *gin.Context) { + //write your code +} + +// @title Swagger Example API +// @version 1.0 +// @description This is a sample server. +// @host localhost:4000 +// @basePath /api +func main() { + r := gin.New() + r.GET("/do-something", api.DoSomething) + r.Run() +} diff --git a/testdata/simple2/web/handler.go b/testdata/simple2/web/handler.go index d9a568692..1ab61b920 100644 --- a/testdata/simple2/web/handler.go +++ b/testdata/simple2/web/handler.go @@ -53,8 +53,8 @@ type Pet struct { Hidden string `json:"-"` UUID uuid.UUID Decimal decimal.Decimal - customString CustomString - customStringArr []CustomString + CustomString CustomString + CustomStringArr []CustomString NullInt sql.NullInt64 `swaggertype:"integer"` Coeffs []big.Float `swaggertype:"array,number"` Birthday TimestampTime `swaggertype:"primitive,integer"`