Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Schema-annotation: add property addJavaDoc #2090

Open
nimo23 opened this issue Dec 3, 2024 · 10 comments
Open

Schema-annotation: add property addJavaDoc #2090

nimo23 opened this issue Dec 3, 2024 · 10 comments
Labels
enhancement New feature or request

Comments

@nimo23
Copy link

nimo23 commented Dec 3, 2024

Currently, I need to duplicate existing Javadoc from the property into the Schema.description tag. This is very annoying and hurts DRY (don’t repeat yourself). It fills the Java class with redundant data and is worse for maintenance, etc..:

/**
 * The description.
 * 
 * <p>
 * Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
 * eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
 * voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
 */
@Schema(readOnly = true, addJavaDoc=true, description = "The description. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy\n"
		+ "	 * eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam\n"
		+ "	 * voluptua. At vero eos et accusam et justo duo dolores et ea rebum.")
private final String description;

Please add a new property for the Schema-Tag, e.g. addJavaDoc = true | false. If the value is set to true, the Javadoc is appended to the OpenAPI description value:

For example:

/**
 * The description.
 * 
 * <p>
 * Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
 * eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
 * voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
 */
@Schema(readOnly = true, addJavaDoc=true)
private final String description;

another example using both addJavaDoc and an explicit description that simply appends the Javadoc after the description value (in this case: "My description. The description page..."):

/**
 * The description.
 * 
 * <p>
 * Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
 * eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
 * voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
 */
@Schema(readOnly = true, addJavaDoc=true, description="My description")
private final String description;

The Javadoc can contain html-tags or Markdown-Syntax (https://openjdk.org/jeps/467) which needs to be considered when putting this in the openapi description value.

@cristalp
Copy link
Contributor

cristalp commented Dec 3, 2024

In my company, we check with CheckStyle that methods have full Javadoc.

However, when a method is well documented with OpenAPI, that's not necessary (DRY, as you stated).

So we just annotate the following:

@SuppressWarnings("javadoc") // Documented with OpenAPI

@nimo23
Copy link
Author

nimo23 commented Dec 3, 2024

@SuppressWarnings("javadoc") // Documented with OpenAPI

This is really a bad workaround. What about the Javadoc for such properites/getters/setters -you don't have one.

@MikeEdgar
Copy link
Member

I'm pretty sure this issue has been raised before. The main problem is that when scanning annotations, the source code (and JavaDoc comments) are no longer available. There might be a way to do this in the Maven plugin where the comments are preprocessed, but I haven't seen any obvious solution yet.

@cristalp
Copy link
Contributor

cristalp commented Dec 3, 2024

We don't document private properties, we document getters and setters, since they are public.

@nimo23
Copy link
Author

nimo23 commented Dec 3, 2024

The main problem is that when scanning annotations, the source code (and JavaDoc comments) are no longer available.

It is a pity, I don't know much about it, I thought it would be possible somehow with an annotation preprocessor. After all, smallrye has access to the classes and the code.

There might be a way to do this in the Maven plugin where the comments are preprocessed, but I haven't seen any obvious solution yet.

This would be a valuable solution. Imagine a Smallrye annotation preprocessor on which compilation (the generation of openapi.yml) is done where it has access to the source code (similar to the preprocessing of JBoss Message Logger, Hibernate Criteria Builder or Jakarta Data, which also creates some files (in this case Java files) live within target/generated/sources-package).

I think when generating from Java to OpenAPI such important things (like setting the description via JavaDoc) should be taken into account.

@nimo23
Copy link
Author

nimo23 commented Dec 3, 2024

Other possible solutions:

@MikeEdgar
Copy link
Member

There might be a way to do this in the Maven plugin where the comments are preprocessed, but I haven't seen any obvious solution yet.

This would be a valuable solution. Imagine a Smallrye annotation preprocessor on which compilation (the generation of openapi.yml) is done where it has access to the source code (similar to the preprocessing of JBoss Message Logger, Hibernate Criteria Builder or Jakarta Data, which also creates some files (in this case Java files) live within target/generated/sources-package).

I think when generating from Java to OpenAPI such important things (like setting the description via JavaDoc) should be taken into account.

Yes, it seems feasible [1] using an annotation processor, or the Maven process-sources or generate-resources phase.

[1] https://docs.oracle.com/en/java/javase/17/docs/api/java.compiler/javax/lang/model/util/Elements.html#getDocComment(javax.lang.model.element.Element)

@nimo23
Copy link
Author

nimo23 commented Dec 3, 2024

@MikeEdgar It would be great to have something like that. Can you do it?

@MikeEdgar
Copy link
Member

@nimo23 I won't have the time for it anytime soon due to competing priorities. We always welcome contributions from the community if you have the spare cycles to give it a try.

@nimo23
Copy link
Author

nimo23 commented Dec 4, 2024

We always welcome contributions from the community if you have the spare cycles to give it a try.

I already tried and played with javax.lang.model.element.ElementVisitor and ElementFilter. A not working example:

 public static void printJavadocsForClass(Class<?> clazz, String fieldName) {
	// TODO: consider all members (not only fields)
        var fields = clazz.getDeclaredFields();
	var fieldList = Arrays.asList(fields);
	var elements = ElementFilter.fieldsIn(fieldList);
		
       // this is not working: cannot find connection between Field and Element
	var elements = ElementFilter.fieldsIn(clazz.getDeclaredFields());
	TypeElement element = elements.getTypeElement(clazz.getName());
	var allMembers = Elements.getAllMembers(element);
    
	var elements = ElementFilter.fieldsIn(Elements.getAllMembers(clazz));
 
      for (Element element : elements) {
          if (element.toString().equals(fieldName)) {
              return elements.getDocComment(element);
          }
      }
      
      return null;
    }

But unfortunately I don't know anything about all these APIs and don't know the subtle connections between these APIs (e.g. Element<->Field) and Smallrye (compilation, process-sources, etc.) in order to be able to provide useful results here. I have to wait until someone with relevant experience has time for this issue.

@MikeEdgar MikeEdgar added the enhancement New feature or request label Dec 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants