• Stars
    star
    298
  • Rank 139,663 (Top 3 %)
  • Language
    Go
  • License
    BSD 2-Clause "Sim...
  • Created over 5 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Generate Go structs from multiple JSON or YAML objects.

go-jsonstruct

PkgGoDev

Generate Go structs from multiple JSON objects.

What does go-jsonstruct do and why should I use it?

go-jsonstruct generates Go structs from multiple JSON objects. Existing Go struct generators such as json-to-go and json2struct take only a single JSON object as input. go-jsonstruct takes multiple JSON objects as input and generates the most specific Go struct possible into which all the input objects can be unmarshalled.

This is useful if you have a collection of JSON objects, where no single object has all properties present, and you want to unmarshal those JSON objects into a Go program. Example collections include:

  • JSON responses received from a REST API with no defined schema.
  • Multiple values from a JSON column in an SQL database.
  • All the JSON documents in a document database.

How do I use go-jsonstruct?

Install go-jsonstruct:

go install github.com/twpayne/go-jsonstruct/v2/cmd/gojsonstruct@latest

Feed it some JSON objects. For example you can feed it with

{
  "age": 37,
  "user_height_m": 2
}

{
  "age": 38,
  "user_height_m": 1.7,
  "favoriteFoods": [
    "cake"
  ]
}

by running

echo '{"age":37,"user_height_m":2}' \
    '{"age":38,"user_height_m":1.7,"favoriteFoods":["cake"]}' \
    | gojsonstruct

This will output:

package main

type T struct {
    Age           int      `json:"age"`
    FavoriteFoods []string `json:"favoriteFoods,omitempty"`
    UserHeightM   float64  `json:"user_height_m"`
}

This example demonstrates:

  • age is always observed as an integer, and so is given type int. The lower-case JSON property age is converted into an exported Go field name Age for compatibility with encoding/json.
  • favoriteFoods is observed as a JSON array, but is not always present, but when it is present it only contains JSON strings, and so is given type []string. The camelCase name favoriteFoods is converted into the exported Go field name FavoriteFoods and is tagged with omitempty.
  • user_height_m is observed as JSON numbers 2 and 1.7, for which the most specific Go type is float64. The snake_case name user_height_m is converted to the exported Go field name UserHeightM.
  • Properties are sorted alphabetically.

go-jsonstruct recursively handles nested array elements and objects. For example, given the following three JSON objects input:

{
  "nested": {
    "bar": true,
    "foo": "baz"
  }
}

{
  "nested": {
    "bar": false,
    "foo": null
  }
}

{
  "nested": {
    "bar": true,
    "foo": ""
  }
}

which you can try by running

echo '{"nested":{"bar":true,"foo":"baz"}}' \
    '{"nested":{"bar":false,"foo":null}}' \
    '{"nested":{"bar":true,"foo":""}}' \
    | gojsonstruct -packagename mypackage -typename MyType

generates the output

package mypackage

type MyType struct {
    Nested struct {
        Bar bool    `json:"bar"`
        Foo *string `json:"foo"`
    } `json:"nested"`
}

This demonstrates:

  • The package name and type name can be set on the command line.
  • The arbitrarily-complex property nested is recursively converted to a nested struct that all values can be unmarshalled to. go-jsonstruct handles array elements in an identical fashion, resolving array elements to the most-specific type.
  • nested.bar is always observed as a JSON bool, and is converted to a field of type bool.
  • nested.foo is observed as a JSON string, a JSON null, and an empty JSON string and is converted to a field of type *string without omitempty. With omitempty, Go's encoding/json omits the field in the two cases of nil and a pointer to an empty string, so there is no way to distinguish between the observed values of null and "". go-jsonstruct falls back to the option of *string without omitempty which means that a value is always present, even if empty.

You can feed it your own data via the standard input, for example if you have a file with one JSON object per line in objects.json you can run:

gojsonstruct < objects.json

To learn about more about the available options, run:

gojsonstruct -help

What are go-jsonstruct's key features?

  • Finds the most specific Go type that can represent all input values.
  • Generates Go struct field names from camelCase, kebab-case, and snake_case JSON object property names.
  • Capitalizes common abbreviations (e.g. HTTP, ID, and URL) when generating Go struct field names to follow Go conventions, with the option to add your own abbreviations.
  • Gives you control over the output, including the generated package name, type name, and godoc-compatible comments.
  • Generates deterministic output based only on the determined structure of the input, making it suitable for incorporation into build pipelines or detecting schema changes.
  • Generates omitempty when possible.
  • Uses the standard library's time.Time when possible.
  • Gracefully handles properties with spaces that cannot be unmarshalled by encoding/json.

How does go-jsonstruct work?

go-jsonstruct consists of two phases: observation and code generation.

Firstly, in the observation phase, go-jsonstruct explores all the input objects and records statistics on what types are observed in each part. It recurses into objects and iterates over arrays.

Secondly, in the code generation phase, go-jsonstruct inspects the gathered statistics and determines the strictest possible Go type that can represent all the observed values. For example, the values 0 and 1 can be represented as an int, the values 0, 1, and 2.2 require a float64, and true, 3.3, and "name" require an any.

License

BSD

More Repositories

1

chezmoi

Manage your dotfiles across multiple diverse machines, securely.
Go
13,267
star
2

go-geom

Package geom implements efficient geometry types for geospatial applications.
Go
848
star
3

dotfiles

My dotfiles, managed with https://chezmoi.io.
Shell
304
star
4

go-polyline

Package polyline implements a Google Maps Encoding Polyline encoder and decoder.
Go
109
star
5

go-kml

Package kml provides convenience methods for creating and writing KML documents.
Go
88
star
6

go-vfs

Package vfs provides an abstraction of the os and io packages that is easy to test.
Go
81
star
7

go-geos

Package geos provides an interface to GEOS.
Go
80
star
8

go-xmlstruct

Generate Go structs from multiple XML documents.
Go
75
star
9

igc2kmz

IGC to Google Earth converter
Python
49
star
10

find-duplicates

Find duplicate files quickly.
Go
46
star
11

go-gpx

Package gpx provides convenience types for reading and writing GPX files.
Go
37
star
12

go-proj

Package proj provides an interface to proj.org.
Go
32
star
13

pgx-geos

Package pgx-geos provides PostGIS and GEOS support for github.com/jackc/pgx/v5 via github.com/twpayne/go-geos.
Go
26
star
14

webglmaps

Blows Leaflet out of the water (if you have a good computer)
JavaScript
24
star
15

gogeom

Geometry functions for Go
Go
21
star
16

paragliding-articles

20
star
17

go-shapefile

Package shapefile provides a native Go reader for ESRI Shapefiles.
Go
19
star
18

go-mbtiles

Package mbtiles reads and writes files in the MBTiles format.
Go
17
star
19

go-svg

Package svg provides convenience methods for creating and writing SVG documents.
Go
17
star
20

go-pinentry

Package pinentry provides a client to GnuPG's pinentry.
Go
16
star
21

flatjson

flatjson converts JSON files to a "flat" representation with one value per line.
Go
15
star
22

flightrecorder

Download tracklogs and upload waypoints for popular flight recorders on UNIX-like operating systems
Python
12
star
23

g-record

IGC g-record signing proof of concept
C
11
star
24

pgx-geom

Package pgx-geom provides PostGIS support for github.com/jackc/pgx/v5 via github.com/twpayne/go-geom.
Go
11
star
25

osm-extract

Extract features from OpenStreetMap PBF files as GeoJSON.
Go
10
star
26

go-darksky

Package darksky implements a client for the Dark Sky API. See https://darksky.net/dev.
Go
9
star
27

go-sse

Package sse implements a Server-Sent Events server.
Go
8
star
28

gopolyline

Google Maps polyline encoding and decoding for Go
Go
8
star
29

go-doarama

Go client library for the Doarama GPS track visualizer
Go
8
star
30

go-pubsub

Package pubsub is a simple publish-subscribe implementation using generics.
Go
7
star
31

find-typos

Find typos.
Go
6
star
32

gpsbabel-flytec

Brauniger/Flytec support for GPSBabel
C
6
star
33

go-meteomatics

Package meteomatics is a client library for the Meteomatics API.
Go
6
star
34

go-shell

Package shell returns the user's shell across multiple platforms.
Go
6
star
35

webgl-utils

Python
6
star
36

go-heap

Package heap implements a generic heap data structure.
Go
6
star
37

go-geobabel

Package geobabel converts geometry types between popular geometry libraries.
Go
6
star
38

go-pinentry-minimal

A version of github.com/twpayne/go-pinentry with minimal dependencies.
Go
5
star
39

go-xdg

Package xdg provides support for the XDG Base Directory Specification.
Go
5
star
40

maxxc

Cross country flight optimiser
C
5
star
41

scoop-bucket

Scoop bucket, see https://scoop.sh.
5
star
42

go-waypoint

Package waypoint reads and writes waypoints in formats used by the free flying community.
Go
4
star
43

vim-igc

VIM syntax highlighting for IGC files
Vim Script
4
star
44

igcscrape

Scrape IGC tracklogs from XC leagues
Python
4
star
45

waypointviewer

Google Maps/Google App Engine application for displaying waypoints
JavaScript
4
star
46

nagios-plugin-bacula

A Nagios plugin for checking Bacula client backups
Python
4
star
47

vscode-testscript

testscript support for Visual Studio Code
3
star
48

libselinux-ruby-puppet

The minimal SELinux bindings for Ruby required to run puppet
C
3
star
49

go-kmz

Package kmz provides convenience methods for creating and writing KMZ files.
Go
3
star
50

nagios-plugin-xserve_raid

A Nagios plugin for checking Apple Xserve RAIDs
Python
3
star
51

forge

A simple utility to clone and open local and remote git repos.
Go
3
star
52

go-xctrack

Package xctrack implements XCTrack's task format.
Go
3
star
53

openlayers-googleearthview

OpenLayers Control to link an OpenLayers map to a Google Earth plugin
JavaScript
3
star
54

go-igc

Package igc handles IGC files.
Go
3
star
55

xcscore-js

Cross country league flight scoring for paragliding
TypeScript
2
star
56

go-affine2d

Package affine2d implements 2D affine transformations.
Go
2
star
57

flytecfs

Userspace filesystem for Flytec and Brauniger flight recorders
Python
2
star
58

ol3-under-the-hood

OpenLayers 3 Under The Hood talk
JavaScript
2
star
59

go-lazy

Package lazy implements lazily-evaluated values.
Go
2
star
60

vim-testscript

VIM syntax highlighting for github.com/rogpeppe/go-internal/testscript
Vim Script
2
star
61

go-fanet

Package fanet generates and parses FANET sentences.
Go
2
star
62

go-vali

Package go-vali implements an API to the FAI's Open Validation Service.
Go
2
star
63

igc2kmz.rb

IGC to Google Earth converter (depreciated Ruby version)
Ruby
2
star
64

netcf-ruby

Ruby bindings for NetCF
C
2
star
65

devfest-zurich2012-whats-hot-on-google-plus

Visualize Google+ posts in a heatmap on Google Maps via Google FusionTables (hosted on Google Drive)
Python
2
star
66

go-serial

Package serial handles serial ports.
Go
2
star
67

gopher-advent-2022-hot-function

Code for my Gopher Advent articles.
Go
2
star
68

tcx2kmz

Garmin Training Center Database to Google Earth converter
Python
2
star
69

python-columnparser

A Python library for parsing columnar tables
Python
2
star
70

aircotini

Download tracklogs from Aircotec flight recorders
1
star
71

pnggrid

Python
1
star
72

vscode-igc

IGC file support for Visual Studio Code.
CUE
1
star
73

tini

Download tracklogs from Brauniger and Flytec flight recorders
C
1
star
74

iripper

Command line interface to the BBC's iPlayer
1
star
75

github-cli

A minimal CLI for making GitHub API calls.
Go
1
star
76

garmini

Download IGC tracklogs from Garmin GPSs
C
1
star
77

go-openaip

Package openaip decodes http://www.openaip.net/ airspace files.
Go
1
star
78

igc2czml

IGC to CZML file converter
Python
1
star
79

closure-toy

Toy project demonstrating Google's Closure tools
JavaScript
1
star
80

go-vfsbilly

Package vfsbilly provides a compatibility layer between github.com/twpayne/go-vfs and github.com/go-git/go-billy.
Go
1
star
81

map-toy

Supporting materials for the JavaScript Romandie talk on "Mapping with JavaScript"
1
star
82

dotfiles-example

Example chezmoi dotfiles
1
star
83

go-nmea

Package nmea parses NMEA sentences.
Go
1
star
84

go-httpd

A trivial HTTP server written in Go
Go
1
star
85

go-xxtea

Package xxtea implements the XXTEA block cipher.
Go
1
star