joffrey-bion / livedoc

A not-so-annotation-based documentation generator for REST and websocket services
MIT License
5 stars 2 forks source link

Add example value annotation for primitive types #46

Open joffrey-bion opened 7 years ago

joffrey-bion commented 7 years ago

As proposed by @ST-DDT in https://github.com/joffrey-bion/livedoc/issues/44, we should create an ApiExample annotation (or a new attribute for @ApiObjectField) in order for the user to provide example values to use in templates.

Since annotations don't support object attributes, this would be limited to primitive value types.

ST-DDT commented 7 years ago

Actually I would go for a more types.

If the value is presented as String you could always fake parse/raw copy it to the target type:

ValueType.DETECT = Default setting, attempt to guess the value type based on the annotated field ValueType.STRING = Just use the string as string. (For Strings and enums) ValueType.INTEGER = For Integers/Longs and BigInteger(?) ValueType.FLOAT/DECIMAL = For Float/Double and BigDecimal(?) ValueType.RAW = For some complex data without proper data schema. (ex Map<String,Object>)

(EDIT: Actually INTEGER, FLOAT/DECIMAL and RAW could be combined to just one because they behave the same)

@interface ApiExample {

    String value();

    ValueType type() default ValueType.DETECT;

}

There is no need to actualy parse the example value as it can be just printed using @JsonRawValue (maybe ValueType.STRING needs automatically added extra quotes).

joffrey-bion commented 7 years ago

Funny that you mention inserting a JSON value, because I thought about it right after posting this issue.

That being said, I'm not sure how much value this brings to the users, especially for complex objects with many fields. I really wanted them to be able to write new MyThing(param1, param2) as default value, and their customized Jackson mapper would have done the serialization job, but annotations don't permit that, which is a pity.

The JSON value approach has a few drawbacks:

Because of this, I'm not sure we should add complexity to Livedoc if there is no real value added. That being said, these drawbacks are not that important considering that providing example JSON for objects should be occasional and not a practice users should apply all over the code base. That's why I may consider it anyway when creating the annotation(s).

Regarding @JsonRawValue, where do you think we could use it? Livedoc template objects are all maps or primitives, so there is no place to put this annotation, unless we deserialize to a declared class. However, in that case, it would be in the user's classes, and this would affect production behaviour, not only the doc. Did you have an idea in particular? Or were you merely pointing at the feature, just in case?

joffrey-bion commented 7 years ago

I also thought about maybe allowing Livedoc to instantiate the object using a no-arg constructor if present. This could be specified via an annotation, or maybe be the default behaviour instead of exploring properties.

For instance, Livedoc could try to find a no-arg constructor on the class, and if not found, fallback to the current behaviour of exploring properties and creating a Map<String, Object>. That way, Livedoc would respect their Jackson config as much as possible.