hapi-swaggered
hapi-swaggered copied to clipboard
missing joi.alternatives fields in model
I have a fairly complex validation object shared on multiple routes. Sometimes with slight modifications which are handled by joi.alternatives:
//generic.id = Joi.alternatives().try(
// Joi.string().length(24).alphanum().lowercase(),
// Joi.object().type(mongoose.Types.ObjectId)
//);
exports.request = Joi.object().keys({
name: Joi.string().required().min(3).max(50).regex(/^[a-z0-9][a-z0-9-]+$/),
state: exports.state.state,
//only require hgroup on create
hgroup: generic.id.when('$isCreate', { is: Joi.any().only(true).required(), then: Joi.required() }),
cdrom: Joi.alternatives().when('cdpath', {is: Joi.any().only(undefined), then:generic.id, otherwise: Joi.any().forbidden()}),
cdpath: Joi.string().regex(/^[^\/\s](?:(?!\/\.\.\/).)+\.iso$/i), //match any string ending with .iso not containing /../ and not beginning with /
ram: Joi.number().integer().required(),
cpuno: Joi.number().integer().required(),
hdds: Joi.array().required().items(Joi.object().rename('id', '_id').keys({
_id: Joi.alternatives().when('$isCreate', {
is: Joi.any().only(true).required(),
then: Joi.any().forbidden(),
otherwise: generic.id
}),
size: Joi.number().integer().required(),
description: Joi.string().max(300),
template: generic.id,
storage: Joi.string().required()
})),
nics: Joi.array().required().items(Joi.object().rename('id', '_id').keys({
_id: Joi.alternatives().when('$isCreate', {
is: Joi.any().only(true).required(),
then: Joi.any().forbidden(),
otherwise: generic.id
}),
ip: Joi.string().required().lowercase().regex(/^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/),
subnet: Joi.string().required().lowercase().regex(/^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/),
gateway: Joi.string().lowercase().regex(/^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/),
vlan: Joi.number().integer().required(),
description: Joi.string().max(300),
})),
}).meta({className:'VMRequest'});
Alternatives fields seems to be ignored completely in generated model:
VMRequest {
name (string),
state (string) = ['stopped' or 'running' or 'restarting' or 'destroying'],
cdpath (string, optional),
ram (integer),
cpuno (integer),
hdds (Array[_idSizeDescriptionTemplateStorageModel]),
nics (Array[_idIpSubnetGatewayVlanDescriptionModel])
}
_idSizeDescriptionTemplateStorageModel {
size (integer),
description (string, optional),
storage (string)
}
_idIpSubnetGatewayVlanDescriptionModel {
ip (string),
subnet (string),
gateway (string, optional),
vlan (integer),
description (string, optional)
}
Yes - joi.alternatives() are currently not supported and will be stripped. I would be interested how your schema should look in swagger 2.0 specs (designed by hand) and then we should have a look how close we can get.
I have a similar problem. The following model actually breaks swagger (with a 500 error):
kindSeparator = Joi.object({
pagingKind: Joi.string().required()["default"]("separator").example("separator").description("Specifies the kind of page.").valid('separator')
}).description("Instruction to render a page separator").meta({
className: 'PaginationPageSeparator'
}).options({
allowUnknown: true,
stripUnknown: true
});
kindPage = Joi.object({
pagingKind: Joi.string().required()["default"]("page").example("page").description("Specifies the kind of page.").valid(['page']),
pageNumber: Joi.number().integer()["default"](0).example(0).description("The zero based page number of this page.").required(),
pageNumberDisplay: Joi.string()["default"]("1").example("1").description("The one based page number as a string, useful for displaying to the end user.").required(),
nextUrl: me.urlOptional("The request url to retrieve this page, or null."),
active: Joi.boolean()["default"](false).example(true).description("Boolean that indicates that this item is the currently active page.").required()
}).description("The description of a single page").meta({
className: 'PaginationPagePage'
}).options({
allowUnknown: true,
stripUnknown: true
});
return Joi.alternatives(kindPage, kindSeparator).description("The description of a single page").meta({
className: 'PaginationPage'
}).options({
allowUnknown: true,
stripUnknown: true
});
THe idea is to have an alternative between object a and b, where a has a specific kind and b another.
@z0mt3c Hello, any updates on this since then? Is it still not working?
Any updates on this?
Edit: mixed up issues
Alternatives have no special implementation yet - but at least it shouldn't throw... will double check with the new version 2.10.0.
As i mentioned earlier: joi.alternatives() are currently not supported and will be stripped. I would be interested how your schema should look in swagger 2.0 specs (designed by hand) and then we should have a look how close we can get.
I know what alternatives do but when i created this module the swagger specs where not capable of polymorphism - at least i didn't find a way. Can u provide me a swagger example schema with polymorphism?
Should be partially possible with Swagger 3.0: https://swagger.io/docs/specification/data-models/inheritance-and-polymorphism/
Discriminator Object adds support for polymorphism - https://swagger.io/specification/#discriminatorObject