-
-
Notifications
You must be signed in to change notification settings - Fork 553
feat: Add @EnumDescription annotation for automatic enum #3125
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
base: main
Are you sure you want to change the base?
Conversation
|
I would suggest adding a test case for when the annotation is used. This both as an illustrative case for how to use it, but also to show that the current implementation actually behaves as expected when utilized. Use the current tests as a suggestion for how they usually are structured. |
|
Thanks for the feedback!
Note that the Which directory structure should I use for the |
|
I prefer the second approach with an integration test as per |
|
This PR adds test cases to verify the EnumDescription annotation functionality:
The tests verify that enum information is properly added to OpenAPI operation descriptions. Please review when convenient. Thanks! |
|
I see now that there exists two different ways of doing integration tests, either in the The difference is that the assertion is made against the entire A bit off topic, but what is the reason for deriving the name from a potential enum value, rather than explicitly having the values in a So the domain is: public enum UserStatus {
ACTIVE,
INACTIVE,
PENDING;
}while the DTO is @Schema(name = "UserStatus", description = "...", example = "...", ....)
public enum UserStatusDTO {
ACTIVE,
INACTIVE,
PENDING;
}The current approach seems like it could potentially cause minor "leakage", since it is not intuitive that anything that goes into an enum's value could reach the client. Sure it is semi-safe, since it is opt-in, but I would always argue for a more strict domain/api segmentation. |
|
Thank you for the detailed feedback. I completely agree with your point about the importance of strict Domain-API segmentation. My primary motivation for implementing @EnumDescription was to solve a clear pain point for frontend developers. They often find it difficult to check the available values and descriptions for an Enum used in API requests/responses. This feature automates embedding this information directly into the operation's description, allowing them to understand and use the API much faster. I fully understand your concern about potential information 'leakage'. As you rightly pointed out, the ideal and safest approach is to separate the internal Domain Enum (like UserStatus) from the DTO Enum (like UserStatusDTO) used for API specifications. This feature was designed with exactly that pattern in mind. The intention is that developers will use @EnumDescription on the DTO Enum field, not the internal Domain Enum. While this still "exposes" information, it's no longer an uncontrolled leak, but rather a controlled specification. The developer explicitly decides which Enum (the DTO-safe one) to expose. I believe the benefit of providing clear, in-spec documentation to frontend developers outweighs the risk of this controlled exposure. This is also precisely why I added the methodName (or fieldName) option—to provide granular control. An Enum can have multiple methods: An internal-logic method (e.g., getInternalReason()) A public-facing description method (e.g., getLabel() or getDescription()) By allowing developers to specify @EnumDescription(methodName = "getLabel"), they can explicitly choose the "safe" method for documentation. This mechanism directly prevents the accidental leakage of internal data and ensures only public-facing information is used. In summary, this feature doesn't prevent or discourage good architecture (like Domain/DTO separation); it enhances it by bridging the information gap between a well-defined DTO (Enum) and the frontend developer who needs to consume it. Thank you again for the insightful feedback, and I look forward to hearing your thoughts. |
|
Thanks for the additional test and the extensive explanation regarding the domain architecture. I find that this looks to be a very helpful approach for the case that you are describing, and since it is opt-in it is totally up to the user to decide what data they expose. Since you have built a good description concatenation, I think it could be nice to showcase that in some test too. I have created some examples here while I investigated some other behavior too. For the Going off track again. The more I think about the usage the more I am curious of whether we could aid the frontend developers even more. My understanding as of now is that the frontend developers look at the swagger presentation of the specification when they build a client integration towards it? So the for example want to define the DTO/the request that should be sent towards an endpoint, and for it they will of course want to mirror the valid values enum parameters. This then would help them define the valid value space for enum field close to the operation (request body, query parameter...), since they would see it within the swagger presentation. Have mimicking or using tools like https://github.com/OpenAPITools/openapi-generator been considered? What they do is that they can generate client DTOs based upon a specification. I personally use the generator in some projects, and it together with |
Description
This PR implements automatic enum description injection into OpenAPI operation descriptions.
It addresses the issue described in #3116
What's Changed
@EnumDescriptionannotation to mark enum fields for automatic description generationUsage Example
Technical Details
EnumDescriptionOperationCustomizerimplementsGlobalOperationCustomizerSpringDocConfigurationFuture Improvements
As mentioned in the original issue, we considered adding support for schema-level descriptions as well.
This could be implemented using
PropertyCustomizerto inject enum descriptions into schema property descriptions.This enhancement could be added in a future PR if there's interest.