feat: Add JSONSchemaHandle() with callbacks into the reflector#136
Open
Adjective-Object wants to merge 2 commits intoinvopop:mainfrom
Open
feat: Add JSONSchemaHandle() with callbacks into the reflector#136Adjective-Object wants to merge 2 commits intoinvopop:mainfrom
Adjective-Object wants to merge 2 commits intoinvopop:mainfrom
Conversation
added 2 commits
February 10, 2024 00:12
…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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change provides
JSONSchemaHandle(ReflectorHandle), a hook in the same vein asJSONSchema() *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.
Usage:
Previously, in order to reference another type in a
JSONSChema() *Schemafunction, you would have to do one of the following:$refin the schema, and ensure elsewhere in your code that you at some point visit the referenced type -- this is error prone, as it requires the reflector to visit your other structs at some pointNames are provisional -- I'm not very good at naming and willing to accept pretty much any suggestions