[Bug?]: Inconsistent schemas generation.
Closed this issue · 2 comments
Hey there!
I have faced an interesting issue.
I've got these types:
type Equal[T huma.SchemaProvider] struct {
Operator string `json:"operator" enum:"EQUAL" doc:"The operator to use for the comparison."`
Value T `json:"value" doc:"The value to compare against."`
}
type In[T huma.SchemaProvider] struct {
Operator string `json:"operator" enum:"IN" doc:"The operator to use for the comparison."`
Values []T `json:"values" doc:"The values to compare against."`
}
type SpecialString string
func (s SpecialString) Schema(r huma.Registry) *huma.Schema {
min, max := 1, 255
return &huma.Schema{
Type: "string",
Description: "A special string type.",
MaxLength: &max,
MinLength: &min,
}
}
type Input struct {
Body struct {
Name Equal[SpecialString] `json:"name"`
Surnames In[SpecialString] `json:"surnames"`
}
}
type Output struct {
Body struct {
Message string `json:"message"`
}
}
The OAS I get ( with api.OpenAPI().Yaml()
):
Full spec
components:
schemas:
EqualSpecialString:
additionalProperties: false
properties:
operator:
description: The operator to use for the comparison.
enum:
- EQUAL
type: string
value:
description: The value to compare against.
type: string
required:
- operator
- value
type: object
ErrorDetail:
additionalProperties: false
properties:
location:
description: Where the error occurred, e.g. 'body.items[3].tags' or 'path.thing-id'
type: string
message:
description: Error message text
type: string
value:
description: The value at the given location
type: object
ErrorModel:
additionalProperties: false
properties:
$schema:
description: A URL to the JSON Schema for this object.
examples:
- https://example.com/schemas/ErrorModel.json
format: uri
readOnly: true
type: string
detail:
description: A human-readable explanation specific to this occurrence of the problem.
examples:
- Property foo is required but is missing.
type: string
errors:
description: Optional list of individual error details
items:
$ref: "#/components/schemas/ErrorDetail"
type: array
instance:
description: A URI reference that identifies the specific occurrence of the problem.
examples:
- https://example.com/error-log/abc123
format: uri
type: string
status:
description: HTTP status code
examples:
- 400
format: int64
type: integer
title:
description: A short, human-readable summary of the problem type. This value should not change between occurrences of the error.
examples:
- Bad Request
type: string
type:
default: about:blank
description: A URI reference to human-readable documentation for the error.
examples:
- https://example.com/errors/example
format: uri
type: string
type: object
InSpecialString:
additionalProperties: false
properties:
operator:
description: The operator to use for the comparison.
enum:
- IN
type: string
values:
description: The values to compare against.
items:
description: A special string type.
maxLength: 255
minLength: 1
type: string
type: array
required:
- operator
- values
type: object
InputBody:
additionalProperties: false
properties:
$schema:
description: A URL to the JSON Schema for this object.
examples:
- https://example.com/schemas/InputBody.json
format: uri
readOnly: true
type: string
name:
$ref: "#/components/schemas/EqualSpecialString"
surnames:
$ref: "#/components/schemas/InSpecialString"
required:
- name
- surnames
type: object
OutputBody:
additionalProperties: false
properties:
$schema:
description: A URL to the JSON Schema for this object.
examples:
- https://example.com/schemas/OutputBody.json
format: uri
readOnly: true
type: string
message:
type: string
required:
- message
type: object
info:
title: My API
version: 1.0.0
openapi: 3.1.0
paths:
/input:
get:
operationId: get-input
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/InputBody"
required: true
responses:
"200":
content:
application/json:
schema:
$ref: "#/components/schemas/OutputBody"
description: OK
default:
content:
application/problem+json:
schema:
$ref: "#/components/schemas/ErrorModel"
description: Error
summary: Get input
The weird thing is that one of the schemas doesn't have MaxLength
and MinLength
EqualSpecialString:
additionalProperties: false
properties:
operator:
description: The operator to use for the comparison.
enum:
- EQUAL
type: string
value:
description: The value to compare against.
type: string
required:
- operator
- value
type: object
whereas another one has it
InSpecialString:
additionalProperties: false
properties:
operator:
description: The operator to use for the comparison.
enum:
- IN
type: string
values:
description: The values to compare against.
items:
description: A special string type.
maxLength: 255
minLength: 1
type: string
type: array
Given that both schemas are based on the same type with the Schema
method, it looks weird.
I'm not sure whether it's a bug or intentional; just want to ask how to make these schemas consistent.
Thank you.
I think it is because T is a slice in your In
type. I'm not sure of the correct solution for how to get Huma to dig into your slice, but maybe you need to make a special schema type just for that reason.
But minLength
and maxLength
are not valid for slices, so that is most likely why it's not coming back.
@krisatverbidio, I'm not sure I got your point.
But minLength and maxLength are not valid for slices
The thing is,In
type receivedminLength
andmaxLength
for each item
type In[T huma.SchemaProvider] struct {
Operator string `json:"operator" enum:"IN" doc:"The operator to use for the comparison."`
Values []T `json:"values" doc:"The values to compare against."`
}
generates
InSpecialString:
additionalProperties: false
properties:
operator:
description: The operator to use for the comparison.
enum:
- IN
type: string
values:
description: The values to compare against.
items:
description: A special string type.
maxLength: 255
minLength: 1
type: string
type: array
Which is expected.
But, this one
type Equal[T huma.SchemaProvider] struct {
Operator string `json:"operator" enum:"EQUAL" doc:"The operator to use for the comparison."`
Value T `json:"value" doc:"The value to compare against."`
}
for some reason doesn't have it.
I would expect to get smth like
EqualSpecialString:
additionalProperties: false
properties:
operator:
description: The operator to use for the comparison.
enum:
- EQUAL
type: string
value:
description: The value to compare against.
maxLength: 255 <-- missed
minLength: 1 <-- missed
type: string
required:
- operator
- value
type: object
Does it make sense?