Back to godoc.org
code.cloudfoundry.org/jsonry

Package jsonry

v1.1.2
Latest Go to latest

The highest tagged major version is .

Published: Oct 1, 2020 | License: Apache-2.0 | Module: code.cloudfoundry.org/jsonry

Overview

JSONry exists to make is easier to marshal and unmarshal nested JSON into Go structures. For example:

{
  "relationships": {
    "space": {
      "data": {
        "guid": "267758c0-985b-11ea-b9ac-48bf6bec2d78"
      }
    }
  }
}

Can be marshaled and unmarshaled using the Go struct:

type s struct { GUID string `jsonry:"relationships.space.data.guid"` }

There is no need to create intermediate structures as would be required with the standard Go JSON parser.

JSONry uses the standard Go parser under the covers. JSONry is a trade-off that delivers usability at a slight cost to performance.

JSONry uses struct tags to specify locations in the JSON document.

When there is neither a "jsonry" or "json" struct tag, the JSON object key name will be the same as the struct field name. For example:

Go: s := struct { Foo string }{Foo: "value"}
JSON: {"Foo": "value"}

When there is a "json" struct tag, it will be interpreted in the same way as the standard Go JSON parser would interpret it. For example:

Go: s := struct { Foo string `json:"bar"` }{Foo: "value"}
JSON: {"bar": "value"}

When there is a "jsonry" struct tag, in addition to working like the "json" tag, it may also contain "." (period) to denote a nesting hierarchy. For example:

Go: s := struct { Foo string `jsonry:"foo.bar"` }{Foo: "value"}
JSON: {"foo": {"bar": "value"} }

Index

Examples

func Marshal

func Marshal(in interface{}) ([]byte, error)

Marshal converts the specified Go struct into JSON. The input must be a struct or a pointer to a struct. Where a field is optional, the suffix ",omitempty" can be specified. This will mean that the field will be omitted from the JSON output if it is a nil pointer or has zero value for the type. When a field is a slice or an array, a single list hint "[]" may be specified in the JSONry path so that the array is created at the correct position in the JSON output.

If a type implements the json.Marshaler interface, then the MarshalJSON() method will be called.

If a type implements the jsonry.Omissible interface, then the OmitJSONry() method will be used to to determine whether or not to marshal the field, overriding any `,omitempty` tags.

The field type can be string, bool, int*, uint*, float*, map, slice, array or struct. JSONry is recursive.

Example

Code:

package main

import (
	"code.cloudfoundry.org/jsonry"
	"fmt"
)

func main() {
	s := struct {
		A    string
		B    string `json:"bee,omitempty"`
		GUID string `jsonry:"relationships.space.data.guid"`
		IDs  []int  `jsonry:"data.entries[].id"`
	}{
		A:    "foo",
		B:    "",
		GUID: "267758c0-985b-11ea-b9ac-48bf6bec2d78",
		IDs:  []int{1, 2, 3, 4, 5},
	}

	json, err := jsonry.Marshal(s)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(json))
}
{"A":"foo","data":{"entries":[{"id":1},{"id":2},{"id":3},{"id":4},{"id":5}]},"relationships":{"space":{"data":{"guid":"267758c0-985b-11ea-b9ac-48bf6bec2d78"}}}}
Example (Recursive)

Code:

package main

import (
	"code.cloudfoundry.org/jsonry"
	"fmt"
)

func main() {
	type s struct {
		A string `jsonry:"f"`
	}
	type t struct {
		B []s `jsonry:"d[].e"`
	}
	type u struct {
		C []t `jsonry:"a.b[].c"`
	}

	data := u{C: []t{{B: []s{{A: "foo"}, {"bar"}}}, {B: []s{{A: "baz"}, {"quz"}}}}}

	json, err := jsonry.Marshal(data)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(json))
}
{"a":{"b":[{"c":{"d":[{"e":{"f":"foo"}},{"e":{"f":"bar"}}]}},{"c":{"d":[{"e":{"f":"baz"}},{"e":{"f":"quz"}}]}}]}}

func Unmarshal

func Unmarshal(data []byte, receiver interface{}) error

Unmarshal parses the specified JSON into the specified Go struct receiver. The receiver must be a pointer to a Go struct containing only fields of the type: string, bool, int*, uint*, float*, map, slice or struct. JSONry is recursive.

If a field implements the json.Unmarshaler interface, then the UnmarshalJSON() method will be called.

Example

Code:

package main

import (
	"code.cloudfoundry.org/jsonry"
	"fmt"
)

func main() {
	json := `
    {
      "A": "foo",
      "bee": "bar",
      "data": {
        "entries": [
          {"id": 1},
          {"id": 2},
          {"id": 3},
          {"id": 4},
          {"id": 5}
        ]
      },
      "relationships": {
        "space": {
          "data": {
            "guid":"267758c0-985b-11ea-b9ac-48bf6bec2d78"}
          }
        }
      }
    }`

	var s struct {
		A    string
		B    string `json:"bee"`
		GUID string `jsonry:"relationships.space.data.guid"`
		IDs  []int  `jsonry:"data.entries.id"`
	}

	if err := jsonry.Unmarshal([]byte(json), &s); err != nil {
		panic(err)
	}

	fmt.Printf("A: %+v\nB: %+v\nGUID: %+v\nIDs: %+v\n", s.A, s.B, s.GUID, s.IDs)
}
A: foo
B: bar
GUID: 267758c0-985b-11ea-b9ac-48bf6bec2d78
IDs: [1 2 3 4 5]

type Omissible

type Omissible interface {
	OmitJSONry() bool
}

Omissible is the interface implemented by types that indicate whether they should be omitted when being marshaled. It allows for more custom control than the `omitempty` tag. This interface overrides any `omitempty` behavior, and it is not necessary to specify `omitempty` with an Omissible type.

Package Files

Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to identifier