santhosh-tekuri/jsonschema

Feature: marshal a default payload based on jsonSchema

Icirus opened this issue · 1 comments

I am looking for a little guidance the Validation is working wonderfully. I am wanting to enhance a payload by setting defaults based on the defaults for a value that are specified in the Json Schema.

I think this could be done similar to the validation process, but the default value would be set in the provided interface. The output of the method could be a []byte for ease of use.

I am unsure what the best method for trying to implement this would be. I have played around with iterating through the properties of the Schema to create a default structure recursively. I am just unsure if there is a better way to achieve the outcome I am after.

default keyword is not clear how it can be used in spec. so such feature cannot be included in library.

but what you are asking can be done trivially as follows:

func Example_FillDefaults() {
	c := jsonschema.NewCompiler()
	c.ExtractAnnotations = true
	err := c.AddResource("schema.json", strings.NewReader(`{
	  "type": "object",
	  "properties": {
		"foo": {"type": "number"},
		"bar": {"type": "string", "default": "baz"}
	  },
	  "required": ["foo", "bar"]
	}`))
	if err != nil {
		panic(err)
	}
	sch, err := c.Compile("schema.json")
	if err != nil {
		panic(err)
	}
	data := map[string]interface{}{"foo": 1}
	fillDefaults(sch, data)
	fmt.Println(data["bar"])
	// Output:
	// baz
}

func fillDefaults(sch *jsonschema.Schema, data interface{}) {
	m, ok := data.(map[string]interface{})
	if !ok {
		return
	}
	if sch.Ref != nil {
		fillDefaults(sch.Ref, data)
	}
	for pname, psch := range sch.Properties {
		pval, ok := m[pname]
                If ok {
                        fillDefaults(psch, pval)
                 } else if psch.Default != nil {
			m[pname] = psch.Default
		}
	}
}

in above example property bar is filled with its default value baz

note that the above implementation is not complete. I am just checking Schema.Ref, but complete implementation has to check allOf, oneOff etc