-- Leo's gemini proxy
-- Connecting to capsule.adrianhesketh.com:1965...
-- Connected
-- Sending request
-- Meta line: 20 text/gemini; charset=utf-8
I had some complex JSON to deserialize into Go structs and a matching JSON schema file. The JSON schema is likely to change a lot over the next few weeks, so I wondered "Is there was a way to create the Go structs automatically based on the JSON schema?"
I searched github.com and found a bunch of packages in various states, so I put together a cut-down version of my app's schema and tried it out.
{ "$schema": "http://json-schema.org/draft-04/schema#", "definitions": { "address": { "id": "address", "type": "object", "description": "Address", "properties": { "houseName": { "type": "string", "description": "House Name", "maxLength": 30 }, "houseNumber": { "type": "string", "description": "House Number", "maxLength": 4 }, "flatNumber": { "type": "string", "description": "Flat", "maxLength": 15 }, "street": { "type": "string", "description": "Address 1", "maxLength": 40 }, "district": { "type": "string", "description": "Address 2", "maxLength": 30 }, "town": { "type": "string", "description": "City", "maxLength": 20 }, "county": { "type": "string", "description": "County", "maxLength": 20 }, "postcode": { "type": "string", "description": "Postcode", "maxLength": 8 } } }, "status": { "type": "object", "properties": { "favouriteCat": { "enum": [ "A", "B", "C", "D", "E", "F" ], "type": "string", "description": "The favourite cat.", "maxLength": 1 } } } }, "properties": { "name": { "type": "string" }, "address": { "$ref": "#/definitions/address" }, "status": { "$ref": "#/definitions/status" } } }
https://github.com/interagent/schematic
Failed to work out of the box at all on my test schema. Issue raised: [0]
./schematic ~/goprojects/src/github.com/a-h/schemagenerators/exampleschema.json schematic: 12:5: expected 'IDENT', found 'import'
https://github.com/idubinskiy/schematyper
Produced some workable-ish Go code. I was expecting the type "Example" to have properties for name, status and address, but it didn't. Either way there are no unit tests so if it does work, it's partly by luck.
package main // generated by "./schematyper /Users/adrian/goprojects/src/github.com/a-h/schemagenerators/exampleschema.json" -- DO NOT EDIT // Address type address struct { County string `json:"county,omitempty"` District string `json:"district,omitempty"` FlatNumber string `json:"flatNumber,omitempty"` HouseName string `json:"houseName,omitempty"` HouseNumber string `json:"houseNumber,omitempty"` Postcode string `json:"postcode,omitempty"` Street string `json:"street,omitempty"` Town string `json:"town,omitempty"` } type exampleschema interface{} type status struct { FavouriteCat string `json:"favouriteCat,omitempty"` }
https://github.com/x-formation/schemagen
Looks OK, but relies on some more packages from the author to do with bin-data which I don't think should be required. Maybe this is for personal use?
https://github.com/snikch/schematype
OK, it's got a beta warning and no unit tests. Let's do this.
Sadly, it doesn't compile right now, left an issue, got a nice message from the author.
https://github.com/schorsch/go-json-schema-tools
Needs some stuff that runs from [1] couldn't be bothered installing the Mercurial tools.
OK, so after this, I got bored and decided to fix the bug in schematic because it has unit tests. The problem was actually with go format on the code that it produces:
https://github.com/interagent/schematic/pull/37
Once I'd fixed that, I got this code out of it, but it still lacked expected properties for the example type - name, address and status.
// Stuff related to making a HTTP call. // Address type Address struct { County string `json:"county" url:"county,key"` // County District string `json:"district" url:"district,key"` // Address 2 FlatNumber string `json:"flatNumber" url:"flatNumber,key"` // Flat HouseName string `json:"houseName" url:"houseName,key"` // House Name HouseNumber string `json:"houseNumber" url:"houseNumber,key"` // House Number Postcode string `json:"postcode" url:"postcode,key"` // Postcode Street string `json:"street" url:"street,key"` // Address 1 Town string `json:"town" url:"town,key"` // City } type Status struct { Favouritecat string `json:"favouritecat" url:"favouritecat,key"` // The favourite cat. }
So, I decided to write something that does what I need over at [2]
While I haven't tested all of the JSON schema features (just the ones I need), it's reasonably well unit tested and produces the output I was looking for:
package main type Address struct { County string `json:"county,omitempty"` District string `json:"district,omitempty"` FlatNumber string `json:"flatNumber,omitempty"` HouseName string `json:"houseName,omitempty"` HouseNumber string `json:"houseNumber,omitempty"` Postcode string `json:"postcode,omitempty"` Street string `json:"street,omitempty"` Town string `json:"town,omitempty"` } type Example struct { Address *Address `json:"address,omitempty"` Name string `json:"name,omitempty"` Status *Status `json:"status,omitempty"` } type Status struct { Favouritecat string `json:"favouritecat,omitempty"` }
I'll be using it to work on a system over the next few weeks, so it's likely to evolve. Ping me if you find it useful!
-- Response ended
-- Page fetched on Sun Apr 28 05:29:52 2024