'Golang struct to Json schema

Hi I need to infer a json schema (github.com/go-openapi/spec.Schema) from a struct :

type Testcase struct {
    Id           string    `json:"id,omitempty"`            // id of this test case
    Name         string    `json:"name,omitempty"`          // name of this test case
    CreationDate time.Time `json:"creation_date,omitempty"` // timestamp when the scenario was first created
    UpdateDate   time.Time `json:"update_date,omitempty"`   // last update timestamp
    Steps        []Step    `json:"steps,omitempty"`         // list of steps  type:"[]StepCcs"
}

I can't find a simple way to do so. I guess that this is a prerequisite for many REST frameworks out there that generate open api spec from the code.

Can someone point me out to a package that contains such helper : ie

func toSchema(obj interface{}) (spec.Schema, error)


Solution 1:[1]

Huma's schema package can do this. Be sure to check out all the validation tags that are available. Example:

import "github.com/danielgtaylor/huma/schema"

// First define some structs:
type Child struct {
    Name string `json:"name" doc:"Child name"`
}

type Hello struct {
    Greeting string    `json:"greeting" maxLength:"80" doc:"A greeting message"`
    Optional uint      `json:"optional,omitempty" doc:"Optional integer example"`
    Child    *Child    `json:"child,omitempty" doc:"Child struct example"`
    Labels   []string  `json:"labels" maxItems:"10" doc:"Array example"`
    Created  time.Time `json:"created" doc:"Created time for this greeting"`
}

// Then later you can do:
s, err := schema.Generate(reflect.TypeOf(Hello{}))

https://go.dev/play/p/4F8NpcgZ4Yh

This will output:

{
  "type": "object",
  "properties": {
    "child": {
      "type": "object",
      "description": "Child struct example",
      "properties": {
        "name": {
          "type": "string",
          "description": "Child name"
        }
      },
      "additionalProperties": false,
      "required": [
        "name"
      ]
    },
    "created": {
      "type": "string",
      "description": "Created time for this greeting",
      "format": "date-time"
    },
    "greeting": {
      "type": "string",
      "description": "A greeting message",
      "maxLength": 80
    },
    "labels": {
      "type": "array",
      "description": "Array example",
      "items": {
        "type": "string"
      },
      "maxItems": 10
    },
    "optional": {
      "type": "integer",
      "description": "Optional integer example",
      "format": "int32",
      "minimum": 0
    }
  },
  "additionalProperties": false,
  "required": [
    "greeting",
    "labels",
    "created"
  ]
}

Solution 2:[2]

https://github.com/invopop/jsonschema

is what you are looking for.

type TestUser struct {
  ID            int                    `json:"id"`
  Name          string                 `json:"name" jsonschema:"title=the name,description=The name of a friend,example=joe,example=lucy,default=alex"`
  Friends       []int                  `json:"friends,omitempty" jsonschema_description:"The list of IDs, omitted when empty"`
  Tags          map[string]interface{} `json:"tags,omitempty" jsonschema_extras:"a=b,foo=bar,foo=bar1"`
  BirthDate     time.Time              `json:"birth_date,omitempty" jsonschema:"oneof_required=date"`
  YearOfBirth   string                 `json:"year_of_birth,omitempty" jsonschema:"oneof_required=year"`
  Metadata      interface{}            `json:"metadata,omitempty" jsonschema:"oneof_type=string;array"`
  FavColor      string                 `json:"fav_color,omitempty" jsonschema:"enum=red,enum=green,enum=blue"`
}

Results in following JSON Schema:

jsonschema.Reflect(&TestUser{})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 manikanta.t