Skip to content

Commit

Permalink
Merge branch '38-use-new-google-jsonapi-library' into 'master'
Browse files Browse the repository at this point in the history
Resolve "Use new google/jsonapi library"

Closes #38

See merge request pace/go-microservice!31
  • Loading branch information
Vincent Landgraf committed Nov 12, 2018
2 parents 6e3461b + 9eee901 commit 9c52388
Show file tree
Hide file tree
Showing 157 changed files with 152,719 additions and 581 deletions.
49 changes: 44 additions & 5 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
[[constraint]]
name = "github.com/google/jsonapi"
branch = "master"
source = "github.com/pace/jsonapi"

[prune]
go-tests = true
Expand Down
4 changes: 2 additions & 2 deletions http/jsonapi/generator/generate_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func (g *Generator) generateResponseInterface(route *route, schema *openapi3.Swa
}()
} else if mt := response.Value.Content.Get(jsonapiContent); mt != nil {
typeReference, err := g.generateTypeReference(route.serviceFunc+methodName,
mt.Schema)
mt.Schema, false)
if err != nil {
return err
}
Expand Down Expand Up @@ -254,7 +254,7 @@ func (g *Generator) generateRequestStruct(route *route, schema *openapi3.Swagger
// add request type
if body != nil {
if mt := body.Value.Content.Get(jsonapiContent); mt != nil {
ref, err := g.generateTypeReference(route.serviceFunc+"Content", mt.Schema)
ref, err := g.generateTypeReference(route.serviceFunc+"Content", mt.Schema, true)
if err != nil {
return err
}
Expand Down
6 changes: 5 additions & 1 deletion http/jsonapi/generator/generate_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ func (g *Generator) goType(stmt *jen.Statement, schema *openapi3.Schema, tags ma
case "binary":
stmt.Index().Byte()
case "date-time":
addValidator(tags, "rfc3339WithoutZone")
if jsonapi, ok := tags["jsonapi"]; ok { // add hint for jsonapi that time is in iso8601 format
tags["jsonapi"] = jsonapi + ",iso8601"
} else {
addValidator(tags, "rfc3339WithoutZone")
}
stmt.Qual("time", "Time")
case "date":
addValidator(tags, "time(2006-01-02)")
Expand Down
82 changes: 52 additions & 30 deletions http/jsonapi/generator/generate_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (g *Generator) BuildTypes(schema *openapi3.Swagger) error {
continue
}

err := g.buildType(name, t, schemaType)
err := g.buildType(name, t, schemaType, make(map[string]string), true)
if err != nil {
return err
}
Expand All @@ -54,27 +54,39 @@ func (g *Generator) BuildTypes(schema *openapi3.Swagger) error {
return nil
}

func (g *Generator) buildType(prefix string, stmt *jen.Statement, schema *openapi3.SchemaRef) error { // nolint: gocyclo
// handle references
if schema.Ref != "" {
// if there is a reference to a type use it
stmt.Op("*").Id(nameFromSchemaRef(schema))
return nil
}

func (g *Generator) buildType(prefix string, stmt *jen.Statement, schema *openapi3.SchemaRef, tags map[string]string, ptr bool) error { // nolint: gocyclo
name := nameFromSchemaRef(schema)
val := schema.Value

switch val.Type {
case "array": // nolint: goconst
if schema.Ref != "" { // handle references
stmt.Id(name)
return nil
}

g.generatedArrayTypes[prefix] = true
return g.buildType(prefix, stmt.Index(), val.Items)
return g.buildType(prefix, stmt.Index(), val.Items, tags, ptr)
case "object": // nolint: goconst
if schema.Ref != "" { // handle references
if ptr {
stmt.Op("*").Id(name)
} else {
stmt.Id(name)
}
return nil
}

if data := val.Properties["data"]; data != nil {
if data.Ref != "" {
return g.buildType(prefix+"Ref", stmt, data)
return g.buildType(prefix+"Ref", stmt, data, make(map[string]string), ptr)
} else if data.Value.Type == "array" { // nolint: goconst
item := prefix + "Item"
stmt.Index().Op("*").Id(item)
if ptr {
stmt.Index().Op("*").Id(item)
} else {
stmt.Index().Id(item)
}
g.addGoDoc(item, data.Value.Description)
itemStmt := g.goSource.Type().Id(item)
return g.structJSONAPI(prefix, itemStmt, data.Value.Items.Value)
Expand All @@ -88,16 +100,21 @@ func (g *Generator) buildType(prefix string, stmt *jen.Statement, schema *openap
return g.structJSONAPI(prefix, stmt, val)
}

return g.buildTypeStruct(prefix, stmt, val)
return g.buildTypeStruct(prefix, stmt, val, ptr)
default:
if schema.Ref != "" { // handle references
stmt.Id(name)
return nil
}

// skip allOf, anyOf and oneOf, as they can't be generated
if len(val.AllOf)+len(val.AnyOf)+len(val.OneOf) > 0 {
log.Warnf("Can't generate allOf, anyOf and oneOf for type %q", prefix)
stmt.Qual("encoding/json", "RawMessage")
return nil
}

err := g.goType(stmt, val, make(map[string]string))
err := g.goType(stmt, val, tags)
if err != nil {
return err
}
Expand All @@ -106,7 +123,7 @@ func (g *Generator) buildType(prefix string, stmt *jen.Statement, schema *openap
return nil
}

func (g *Generator) buildTypeStruct(name string, stmt *jen.Statement, schema *openapi3.Schema) error {
func (g *Generator) buildTypeStruct(name string, stmt *jen.Statement, schema *openapi3.Schema, ptr bool) error {
// build regular struct
fields, err := g.generateStructFields(name, schema, false)
if err != nil {
Expand All @@ -120,7 +137,11 @@ func (g *Generator) buildTypeStruct(name string, stmt *jen.Statement, schema *op

g.goSource.Add(t).Struct(fields...)
// use new struct pointer
stmt.Op("*").Id(name)
if ptr {
stmt.Op("*").Id(name)
} else {
stmt.Id(name)
}
return nil
}

Expand All @@ -131,7 +152,7 @@ func (g *Generator) buildTypeStruct(name string, stmt *jen.Statement, schema *op

// references the type from the schema or generates a new type (inline)
// and returns
func (g *Generator) generateTypeReference(fallbackName string, schema *openapi3.SchemaRef) (jen.Code, error) {
func (g *Generator) generateTypeReference(fallbackName string, schema *openapi3.SchemaRef, noPtr bool) (jen.Code, error) {
// handle references
if schema.Ref != "" {
// if there is a reference to a type use it
Expand All @@ -145,18 +166,25 @@ func (g *Generator) generateTypeReference(fallbackName string, schema *openapi3.
if g.generatedArrayTypes[id] {
return jen.Id(id), nil
}
if noPtr {
return jen.Id(id), nil
}

return jen.Op("*").Id(id), nil
}

// generate type and doc as a fallback (if no ref provided)
t, ok := g.newType(fallbackName)
if ok {
g.addGoDoc(fallbackName, schema.Value.Description)
err := g.buildType(fallbackName, g.goSource.Add(t), schema)
err := g.buildType(fallbackName, g.goSource.Add(t), schema, make(map[string]string), true)
if err != nil {
return nil, err
}
}
if noPtr {
return jen.Id(fallbackName), nil
}

return jen.Op("*").Id(fallbackName), nil
}
Expand Down Expand Up @@ -192,7 +220,7 @@ func (g *Generator) structJSONAPI(prefix string, stmt *jen.Statement, schema *op
if meta != nil {
metaAttr := jen.Id("Meta")
defer func() {
err := g.buildTypeStruct(prefix+"Meta", metaAttr, meta.Value)
err := g.buildTypeStruct(prefix+"Meta", metaAttr, meta.Value, true)
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -226,7 +254,7 @@ func (g *Generator) structJSONAPI(prefix string, stmt *jen.Statement, schema *op
func (g *Generator) generateAttrField(prefix, name string, schema *openapi3.SchemaRef, tags map[string]string) (*jen.Statement, error) {
field := jen.Id(goNameHelper(name))

err := g.buildType(prefix+goNameHelper(name), field, schema)
err := g.buildType(prefix+goNameHelper(name), field, schema, tags, false)
if err != nil {
return nil, err
}
Expand All @@ -249,7 +277,7 @@ func (g *Generator) generateStructFields(prefix string, schema *openapi3.Schema,
for _, attrName := range keys {
attrSchema := schema.Properties[attrName]
tags := make(map[string]string)
addJSONAPITags(tags, attrName, jsonAPIObject)
addJSONAPITags(tags, "attr", attrName)
addRequiredOptionalTag(tags, attrName, schema)

// generate attribute field
Expand All @@ -274,7 +302,7 @@ func (g *Generator) generateStructRelationships(prefix string, schema *openapi3.
for _, relName := range keys {
relSchema := schema.Properties[relName]
tags := make(map[string]string)
addJSONAPITags(tags, relName, jsonAPI)
addJSONAPITags(tags, "relation", relName)
addRequiredOptionalTag(tags, relName, schema)

// check for data
Expand Down Expand Up @@ -371,13 +399,7 @@ func addRequiredOptionalTag(tags map[string]string, name string, schema *openapi
}
}

func addJSONAPITags(tags map[string]string, name string, jsonAPI bool) {
// Add json-api tag
if jsonAPI {
tags["jsonapi"] = fmt.Sprintf("attr,%s,omitempty", name)
} else {
tags["jsonapi"] = fmt.Sprintf("%s,omitempty", name)
}
// Add json tag
func addJSONAPITags(tags map[string]string, kind, name string) {
tags["jsonapi"] = fmt.Sprintf("%s,%s,omitempty", kind, name)
tags["json"] = fmt.Sprintf("%s,omitempty", name)
}
Loading

0 comments on commit 9c52388

Please sign in to comment.