swaggest / jsonschema-go

JSON Schema mapping for Go
https://pkg.go.dev/github.com/swaggest/jsonschema-go
MIT License
112 stars 14 forks source link

Custom schemas properties using tags #68

Closed tpoxa closed 1 year ago

tpoxa commented 1 year ago

It looks like custom tags being ignored

package main

import (
    "encoding/json"
    "fmt"
    "github.com/swaggest/jsonschema-go"
)

type Recipient struct {
    Name  string `json:"name" title:"Name" default:"John Doe" colSpan:"col-span-6"`
    Email string `json:"email" required:"true" title:"Email" format:"email" default:"johndoe@example.com" colSpan:"col-span-6"`
}

func main() {
    r := jsonschema.Reflector{}
    sh, _ := r.Reflect(Recipient{})

    j, _ := json.MarshalIndent(sh, "", " ")
    fmt.Println(string(j))
}

The result:

{
 "required": [
  "email"
 ],
 "properties": {
  "email": {
   "title": "Email",
   "default": "johndoe@example.com",
   "type": "string",
   "format": "email"
  },
  "name": {
   "title": "Name",
   "default": "John Doe",
   "type": "string"
  }
 },
 "type": "object"
}

Any chance to have custom properties presented?

I've checked Intercept things but did not find a solution.

Thank you.

vearutop commented 1 year ago

Hello, that's true, default reflection ignores any unknown field tags.

It is possible to add them manually with jsonschema.InterceptProperty, please check an example:

https://go.dev/play/p/hQW4YL3kSuk

package main

import (
    "encoding/json"
    "fmt"
    "reflect"

    "github.com/swaggest/jsonschema-go"
)

type Recipient struct {
    Name  string `json:"name" title:"Name" default:"John Doe" colSpan:"col-span-6"`
    Email string `json:"email" required:"true" title:"Email" format:"email" default:"johndoe@example.com" colSpan:"col-span-6"`
}

func main() {
    r := jsonschema.Reflector{}
    sh, _ := r.Reflect(Recipient{}, jsonschema.InterceptProperty(func(name string, field reflect.StructField, propertySchema *jsonschema.Schema) error {
        if colSpan, ok := field.Tag.Lookup("colSpan"); ok {
            propertySchema.WithExtraPropertiesItem("colSpan", colSpan)
        }

        return nil
    }))

    j, _ := json.MarshalIndent(sh, "", " ")
    fmt.Println(string(j))
}
{
 "required": [
  "email"
 ],
 "properties": {
  "email": {
   "title": "Email",
   "default": "johndoe@example.com",
   "type": "string",
   "format": "email",
   "colSpan": "col-span-6"
  },
  "name": {
   "title": "Name",
   "default": "John Doe",
   "type": "string",
   "colSpan": "col-span-6"
  }
 },
 "type": "object"
}
tpoxa commented 1 year ago

Awesome. Thanks