routing-controllers-openapi
routing-controllers-openapi copied to clipboard
Map with string array as values
hi, I would like to generate OpenAPI specs for a payload which would contain a map with string[] as values.
Example:
{
'combinations': {
'combination1': ['elem1', 'elem2'],
'combination2': ['elem2', 'elem3'],
},
}
I can't seem to find a right way to annotate class properties in order to generate correct specs that would reflect above JSON shape.
I tried few approaches but nothing seemed to work:
string[] as values
export class Body {
@ValidateNested({each: true})
public combinations: Map<string, string[]>;
}
another one using class extending string[]
export class StringArray extends Array<string>{}
export class Body {
@ValidateNested({each: true})
@Type(() => StringArray)
public combinations: Map<string, StringArray>;
}
Does 'routing-controllers-openapi' support such case?
Thanks! Tom
@tomashq, Did you find a solution for this?
It's likely possible to define your custom schema with the @JSONSchema annotation. However I'm not sure how to do it exactly. Does anyone know more details here? See also: https://github.com/epiphone/class-validator-jsonschema#validatenested-and-arrays
Simple examples for arrays and maps I got to work:
@ValidateNested({ each: true })
@Type(() => YourObjectType)
items: YourObjectType[]
For simple object/maps the same works:
@ValidateNested({ each: true })
@Type(() => YourObjectType)
items?: Map<string, YourObjectType>;
What's missing right now is to annotate a class with Type Information. e.g. First example of @tomashq: The StringArray class does not add any information, because at runtime there's still no type information for that class and we can't annotate a class with the required @ValidateNested, @Type(() => string).
I'll open another ticket since this looks like a more generic issue.
Workaround in general is to define the JSONSchema manually. I provided an example in #98. Also for simple strings I had troubles defining the type correct so I did this:
@IsArray({ each: true })
@JSONSchema({
type: 'array',
items: {
type: 'string'
}
})
data: string[];
For your case @tomashq you can use this:
export class Body {
@IsObject()
@JSONSchema({
type: 'object',
properties: {
'{key}': {
type: 'array',
items: {
type: 'string'
}
}
}
})
public combinations: Map<string, string[]>;
}
That shows the following JSONSchema in swagger for me:
"combinations": {
"{key}": [
"string"
]
}
Now this ticket can be closed.
would this way work for @IsArray() too? I am trying to bulk insert with array, but my items in array is null in swagger
@IsArray() @ValidateNested({ each: true }) @Type(() => CreatePostDto) public posts: CreatePostDto[]
I actually found a better way for Object in arrays. You can use JSONSchema for better Swagger examples. put your DTOs in "CreatePostDTO"
@IsArray()
@JSONSchema({
type: 'array',
items: {
$ref: '#/components/schemas/CreatePostDTO'
}
})
@Type(() => CreatePostDTO)
public posts: CreatePostDTO[]
my example would look like this
my CreatePostDTO looks like this
export class UpdatePostDto {
@IsNotEmpty()
public title: string;
@IsNotEmpty()
public content: string;
}