Skip to content

Commit

Permalink
[PIPE-952] Add optional flag (#19)
Browse files Browse the repository at this point in the history
* Implement optional value to allow optional fields in certain cases

* Remove required where it's not been explicitly tested, add optional
  • Loading branch information
welps authored Dec 7, 2018
1 parent fd57ac8 commit a24f638
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 13 deletions.
2 changes: 1 addition & 1 deletion case_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package jsonschema

type ExampleCase struct {
Type string `json:"type" jsonschema:"required;enum="bool|int|string"`
Type string `json:"type" jsonschema:"optional"`
}

type IntPayload struct {
Expand Down
3 changes: 0 additions & 3 deletions fixtures/case.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,6 @@
"type": "string"
}
},
"required": [
"type"
],
"type": "object"
},
"jsonschema.IntPayload": {
Expand Down
18 changes: 18 additions & 0 deletions reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,7 @@ func (t *Type) arrayKeywords(tags []string) {
}
}

// `json:"-"` and `json:"omitempty"` make the field optional
func requiredFromJSONTags(tags []string) bool {
if ignoredByJSONTags(tags) {
return false
Expand All @@ -604,6 +605,7 @@ func requiredFromJSONTags(tags []string) bool {
return true
}

// Setting RequiredFromJSONSchemaTags to true allows usage of the `required` tag to make a field required
func requiredFromJSONSchemaTags(tags []string) bool {
if ignoredByJSONSchemaTags(tags) {
return false
Expand All @@ -616,6 +618,20 @@ func requiredFromJSONSchemaTags(tags []string) bool {
return false
}

// `jsonschema:"optional"` will make the field optional
//
// The use case for this is when you are taking json input where validation on a field should be optional
// but you do not want to declare `omitempty` because you serialize the struct to json to a third party
// and the fields must exist (such as a field that's an int)
func remainsRequiredFromJSONSchemaTags(tags []string, currentlyRequired bool) bool {
for _, tag := range tags {
if tag == "optional" {
return false
}
}
return currentlyRequired
}

func ignoredByJSONTags(tags []string) bool {
return tags[0] == "-"
}
Expand Down Expand Up @@ -647,6 +663,8 @@ func (r *Reflector) reflectFieldName(f reflect.StructField, t reflect.Type) (str
required = requiredFromJSONSchemaTags(jsonSchemaTags)
}

required = remainsRequiredFromJSONSchemaTags(jsonSchemaTags, required)

if jsonTags[0] != "" {
name = jsonTags[0]
}
Expand Down
2 changes: 1 addition & 1 deletion reflect_application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package jsonschema
import "reflect"

type Application struct {
Type string `json:"type" jsonschema:"required"`
Type string `json:"type"`
}

type ApplicationValidation struct {
Expand Down
10 changes: 5 additions & 5 deletions reflect_test_user_one_of_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package jsonschema
import "reflect"

type TestUserOneOf struct {
Tester Tester `json:"tester" jsonschema:"required"`
Developer Developer `json:"developer" jsonschema:"required"`
Tester Tester `json:"tester"`
Developer Developer `json:"developer"`
}

func (user TestUserOneOf) OneOf() []reflect.StructField {
Expand All @@ -24,7 +24,7 @@ type Tester struct {
// Developer struct
type Developer struct {
Experience StringOrNull `json:"experience" jsonschema:"minLength=1"`
Language StringOrNull `json:"language" jsonschema:"required,pattern=\\S+"`
Language StringOrNull `json:"language" jsonschema:"pattern=\\S+"`
HardwareChoice Hardware `json:"hardware"`
}

Expand All @@ -34,8 +34,8 @@ type StringOrNull struct {
}

type Hardware struct {
Brand string `json:"brand" jsonschema:"required,notEmpty"`
Memory int `json:"memory" jsonschema:"required"`
Brand string `json:"brand" jsonschema:"notEmpty"`
Memory int `json:"memory"`
}

type Laptop struct {
Expand Down
6 changes: 3 additions & 3 deletions reflect_test_user_packages_handling_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
)

type TestUserPackage struct {
Tester TesterPackage `json:"tester" jsonschema:"required"`
Developer DeveloperPackage `json:"developer" jsonschema:"required"`
Tester TesterPackage `json:"tester"`
Developer DeveloperPackage `json:"developer"`
}

func (user TestUserPackage) OneOf() []reflect.StructField {
Expand All @@ -29,7 +29,7 @@ type TesterPackage struct {
// Developer struct
type DeveloperPackage struct {
Experience StringOrNull1 `json:"experience" jsonschema:"minLength=1"`
Language StringOrNull1 `json:"language" jsonschema:"required,pattern=\\S+"`
Language StringOrNull1 `json:"language" jsonschema:"pattern=\\S+"`
HardwareChoice v1.Hardware `json:"hardware"`
HardwareChoic v2.Hardware `json:"hardware1"`
}
Expand Down

0 comments on commit a24f638

Please sign in to comment.