RegisterModel allows a model to be registered manually so that additional configuration can be applied. The schema returned can be modified as required.
(model Model, opts ...ModelOpts)
| 259 | // RegisterModel allows a model to be registered manually so that additional configuration can be applied. |
| 260 | // The schema returned can be modified as required. |
| 261 | func (api *API) RegisterModel(model Model, opts ...ModelOpts) (name string, schema *openapi3.Schema, err error) { |
| 262 | // Get the name. |
| 263 | t := model.Type |
| 264 | name = api.getModelName(t) |
| 265 | |
| 266 | // If we've already got the schema, return it. |
| 267 | var ok bool |
| 268 | if schema, ok = api.models[name]; ok { |
| 269 | return name, schema, nil |
| 270 | } |
| 271 | |
| 272 | // It's known, but not in the schemaset yet. |
| 273 | if knownSchema, ok := api.KnownTypes[t]; ok { |
| 274 | // Objects, enums, need to be references, so add it into the |
| 275 | // list. |
| 276 | if shouldBeReferenced(&knownSchema) { |
| 277 | api.models[name] = &knownSchema |
| 278 | } |
| 279 | return name, &knownSchema, nil |
| 280 | } |
| 281 | |
| 282 | var elementName string |
| 283 | var elementSchema *openapi3.Schema |
| 284 | switch t.Kind() { |
| 285 | case reflect.Slice, reflect.Array: |
| 286 | elementName, elementSchema, err = api.RegisterModel(modelFromType(t.Elem())) |
| 287 | if err != nil { |
| 288 | return name, schema, fmt.Errorf("error getting schema of slice element %v: %w", t.Elem(), err) |
| 289 | } |
| 290 | schema = openapi3.NewArraySchema().WithNullable() // Arrays are always nilable in Go. |
| 291 | schema.Items = getSchemaReferenceOrValue(elementName, elementSchema) |
| 292 | case reflect.String: |
| 293 | schema = openapi3.NewStringSchema() |
| 294 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: |
| 295 | schema = openapi3.NewIntegerSchema() |
| 296 | case reflect.Float64, reflect.Float32: |
| 297 | schema = openapi3.NewFloat64Schema() |
| 298 | case reflect.Bool: |
| 299 | schema = openapi3.NewBoolSchema() |
| 300 | case reflect.Pointer: |
| 301 | name, schema, err = api.RegisterModel(modelFromType(t.Elem()), WithNullable()) |
| 302 | case reflect.Map: |
| 303 | // Check that the key is a string. |
| 304 | if t.Key().Kind() != reflect.String { |
| 305 | return name, schema, fmt.Errorf("maps must have a string key, but this map is of type %q", t.Key().String()) |
| 306 | } |
| 307 | |
| 308 | // Get the element schema. |
| 309 | elementName, elementSchema, err = api.RegisterModel(modelFromType(t.Elem())) |
| 310 | if err != nil { |
| 311 | return name, schema, fmt.Errorf("error getting schema of map value element %v: %w", t.Elem(), err) |
| 312 | } |
| 313 | schema = openapi3.NewObjectSchema().WithNullable() |
| 314 | schema.AdditionalProperties.Schema = getSchemaReferenceOrValue(elementName, elementSchema) |
| 315 | case reflect.Struct: |
| 316 | schema = openapi3.NewObjectSchema() |
| 317 | if schema.Description, schema.Deprecated, err = api.getTypeComment(t.PkgPath(), t.Name()); err != nil { |
| 318 | return name, schema, fmt.Errorf("failed to get comments for type %q: %w", name, err) |