Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add JSONSchemaHandle() with callbacks into the reflector #136

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Commits on Feb 10, 2024

  1. Add JSONSchemaHandle() allowing the consumer to call-back into the re…

    …flector
    
    Previously, in order to reference another type in your schema, you would have to do one of the following:
    1. duplicate the schema declaration of that type inline in the schema, which is cumbersome for types with inferred reflection-based schemas
    2. use a manual `$ref` in the schema, and ensure elsewhere in your code that you at some point visit the referenced type
    3. create a reflector(), reflect on the type you want to reference, and introspect on the generated schema to pull out the type definition
      - this is especially error-prone because you lose type information for _other_ referenced types, and you also run into infinite-recursion issues when dealing with cyclical types.
    
    This change provides `JSONSchemaHandle(ReflectorHandle)`, a hook in the same vein as `JSONSchema() *jsonschema.Schema`, but with an api object to call back into the Reflector to get rhe schema handle for a type.
    
    This allows the user to manually create complex schemas, e.g. using OneOf, AllOf, etc, while referencing other types from within their codebase, and still getting the automatic code-generation from those structs/enums.
    
    ```go
    type ReflectorHandle struct {
    	SchemaFor     func(t any) *Schema
    	SchemaForType func(t reflect.Type) *Schema
    }
    ```
    
    Usage:
    ```go
    type TypeOne struct {
    	Type     string `json:"type" jsonschema:"required,enum=one"`
    	OneField string `json:"oneField"`
    }
    type TypeTwo struct {
    	Type     string `json:"type" jsonschema:"required,enum=two"`
    	TwoField string `json:"twoField"`
    }
    type RecursiveType struct {
    	Type string         `json:"type" jsonschema:"required,enum=recursive"`
    	Self *RecursiveType `json:"self"`
    }
    
    func (HandleTest) JSONSchemaHandle(handle ReflectorHandle) *Schema {
    	schema := &Schema{
    		OneOf: []*Schema{
    			handle.SchemaFor(TypeOne{}),
    			handle.SchemaForType(reflect.TypeOf(TypeTwo{})),
    			handle.SchemaFor(RecursiveType{}),
    		},
    	}
    	return schema
    }
    ```
    
    Names are provisional -- I'm not very good at naming and willing to accept pretty much any suggestions
    Max Huang-Hobbs authored and Max Huang-Hobbs committed Feb 10, 2024
    Configuration menu
    Copy the full SHA
    290bba8 View commit details
    Browse the repository at this point in the history

Commits on Feb 12, 2024

  1. add support for MapWithHandle

    Max Huang-Hobbs authored and Max Huang-Hobbs committed Feb 12, 2024
    Configuration menu
    Copy the full SHA
    a153774 View commit details
    Browse the repository at this point in the history