Open Wicpar opened 4 years ago
I am really waiting for this feature to show all possible errors in my api
Oh, I'm still waiting... I hope you'll make it as soon as you can...
Hi @Wicpar, I implemented an @Example
annotation for the fields and wanted to run it by you in case you think it's useful and want me to add a PR.
Let me know if you prefer me to open a different issue for this, I thought the subjects were somewhat connected.
The rationale behind the change is that I'm using Rapidoc instead of Swagger UI, and Rapidoc ignores the examples entirely and uses only the "example" attribute each field.
The annotation is used like this:
data class Result(
@Description("Hexadecimal UID of the card")
@Example("04D3AC7A124A80")
var cardUID: String = "",
@Description("Card type: A, B o M")
@Example("M")
var cardType: String = "",
@Example(intValue = 200)
var someIntField: Int = 0
)
This is the implementation:
@Target(AnnotationTarget.TYPE, AnnotationTarget.PROPERTY)
@SchemaProcessorAnnotation(ExampleValueProcessor::class)
annotation class Example(
val stringValue: String = "",
val intValue: Int = 0,
val longValue: Long = 0,
val doubleValue: Double = 0.0,
val boolValue: Boolean = false,
val isNull: Boolean = false
)
The processor is the only thing that's a little ugly, but probably can be improved:
object ExampleValueProcessor: SchemaProcessor<Example> {
@Suppress("UNCHECKED_CAST")
override fun process(model: SchemaModel<*>, type: KType, annotation: Example): SchemaModel<*> {
when (model) {
is SchemaModel.SchemaModelLitteral<*> -> {
(model as SchemaModel.SchemaModelLitteral<Any?>).apply {
when(model.type) {
DataType.integer, DataType.number -> {
example = when {
annotation.intValue != 0 -> annotation.intValue
annotation.longValue != 0L -> annotation.longValue
annotation.doubleValue != 0.0 -> annotation.doubleValue
annotation.stringValue.isNotBlank() -> BigDecimal(annotation.stringValue)
else -> 0
}
}
DataType.boolean -> {
example = annotation.boolValue
}
DataType.`object`, DataType.array -> {
throw Exception("Type ${model.type} not supported for examples")
}
else -> { /* string */
example = annotation.stringValue
}
}
}
}
is SchemaModel.SchemaModelEnum<*> -> {
(model as SchemaModel.SchemaModelEnum<Any?>).apply {
example = annotation.stringValue
}
}
else -> {
throw Exception("${annotation::class} can't be applied to $model")
}
}
return model
}
}
The approach I would have taken is to just take a string and convert it based on type
, this would allow for objects as json examples without additional effort.
@JavierPAYTEF What do you think about that, but a purely string based annotation that parses the content as json (or other based on a secondary optional property) ?
@Wicpar Hi, sorry, I've had a lot of work this past few weeks, I couldn't work on this. Regarding your approach, could you explain a little more? The advantage with your approach would be that we could use non-native types, like arrays for example, but the examples would still need to be simple, and not objects, since this tag is for field examples. Probably another approach would be needed for full object examples. Do you maybe have anything you think would be useful as a guide to implement this? If you saw my code it's not exhaustive with the types at all.
There is no way to handle multiple types of primitives in annotations in a cleaner way than you did.
The cleanest is really to use a string with intellij @Language
injection for json. But if you want to keep it with primitives the way you went with is the way to go. Maybe have a way to allow 0 values by selecting the annotation value based on KType.
Do you maybe have an example or somewhere I can read some documentation? I tried researching on my own but my knowledge of annotations is not the best, so I will follow your lead since you probably know more than me in that regard. Let me know a little more about how you would go about implementing it and I'll try to follow your lead.
I don't know if an exhaustive guide about annotations exist, i just learned how to use them by fiddling around with them, and looking at annotation-heavy projects like spring.
A system needs to be created that allows to provide one or more examples with their metadata without adding bulk to the minimal configuration.