How can I use my own annotation for Swagger? - java

How can I use my own annotation for building swagger ui page.
For example I defined annotation and use it:
#PUT
#MyOwnAnnotationForAdditionalPropInSwagger(value = "Some text")
#Path( "/{carId}" )
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#ApiOperation(
value = "Updates car info"
)
public Response patchItem(#ApiParam(value = "Fields to update") Car item) {
/*some code*/
}
After that probably I should extend some class from swagger-core and specify to scan my annotation (#MyOwnAnnotationForAdditionalPropInSwagger).
As result I want to see additional column in swagger ui with my text.
How I can realize it? What class I need to extend?

The swagger 2.0 supports custom fields, there was a Pull Request for this back in 2013 (https://github.com/swagger-api/swagger-node/pull/47).
While apparently it's easy to add the custom fields, since they are not present in the Swagger 2.0 spec, Swagger-UI won't display them by default.
For this to work you will have to change a couple of things.
Implement the desired annotation in your parser implementation (ie. swagger-core or swagger-php) if it doesn't exist.
Clone and modify swagger-ui to display your custom field as you wish.
Note that by doing this you will in fact violate the swagger json schema (https://github.com/swagger-api/swagger-spec/blob/master/schemas/v2.0/schema.json) and any third party validators you may use will fail.

I believe what you are trying to do ca be achieved extending the swagger core reader as described in swagger documentation. Here is an example in one of my projects.

Related

Swagger UI - customize Models section layout

I'd like to make some customizations in models layouts, or at least add some comments.
Here is how it looks like by default:
I use java springfox for swagger UI.
Here is my Swagger config:
Is it possible to do that?
It seems to me that you are looking for #ApiModelProperty. You can annotate each attribute with it and include value parameter as the description. Additional details at https://www.baeldung.com/swagger-apiparam-vs-apimodelproperty.
#ApiModelProperty(value = "Your description")
int fromLocation;

Excluding entities from Swagger model

We are using Swagger to model our API with Spring annotations:
#Operation(summary = "Creates a post for given user.")
#PostMapping("/post")
open fun createPost(
#RequestParam("userId") user: User,
)
The issue we are having is that Swagger does not know there is a logic behind and we are only passing userId: Long for which the user is loaded by Hibernate.
The model of User contains several #OneToOne, #ManyToOne, #OneToMany relations to other entities and Swagger builds the model of User with all of them. This causes the model to be huge and some of our Swagger docs wouldn't even load in the browser as the model is in the size of megabytes.
Is there a way to tell Swagger:
to ignore specific entity/entities
to enforce different type (in this case Long)
Ideally something like:
#Operation(summary = "Creates a post for given user.")
#PostMapping("/post")
open fun createPost(
#SwaggerType(Long::class)
#RequestParam("userId")
user: User,
)
The cleanest way is to use Springfox with an alternate type rule. See no 10 in the examples given here:
https://springfox.github.io/springfox/docs/current/#springfox-spring-mvc-and-spring-boot
This enables you to completely replace your User class by any other (fake) class that you want to show to the Swagger user, without polluting your model with workarounds - but still staying transparent in your code.
There are a few options that can be tried:
Using inheritance with User Model, you can just define a SuperClass-childClass mapping with User class only containing the userId, and the child class that inherits from it will be holding the other attributes for you. In this way, the input will only be the userId with minimal effort.
Using JsonIgnore, but this works really well while returning the response.
With OpenAPI, Swagger has introduced the capability to use specific properties from the request class. More can be read from
https://swagger.io/docs/specification/describing-request-body/
you can use two different class,a basic class and a senior class,and the senior extends the basic,use basic class in API;
or you can use #JsonIgnore if you don't want to show the field ,like:
#JsonIgnore
private String name;
Beacuse Swagger use jackson to json, if you shield the field by jackson,it will not appear.
In swagger
you can use #ApiModelProperty(hidden = true),This is the perfect way

How to set response model as a class in Springfox Swagger?

I using OperationBuilderPlugin of Springfox Swagger to process some custom written annotations. However, for operation related annotations, I need to specify response model as well.
Now, response model requires a ModelReference object. I want to set the class that is actually returned from the endpoint as a response. However, it does not recognize that. I have seen people only putting values like string, Error, etc.
Here's some code.
My operations related plugin's troublemaking piece of code.
context.operationBuilder()
.summary(...)
.produces(...)
.consumes(...)
.responseModel(new ModelRef("DefaultResponse")).build()
My DefaultResponse class has nothing special. It's just a POJO.
#ApiModel
class DefaultResponse {
private String message;
...
}
It turns out, we can add additional models to our Docket definition. So, adding additionalModels(typeResolver.resolve (DefaultResponse.class) ) to the bean definition solved it. We can autowire the com.fasterxml.classmate.TypeResolver object.
I found the answer here

How to annotate a request body that is oneOf external models?

I'm working on documenting an API made with RESTeasy + Jackson in Java using Swagger/OpenAPI (version 1.5.18 - I did add in v3 OAS 2.0.1 to try oneOf/anyOf). One of the endpoints takes in a String as a request body, which is then transformed into one of several classes. The documentation needs to display each of these models so that users can see them. The models are defined in another project. Is there a way to do this through annotations? The closest thing I've found is adding #RequestBody(content=#Content(schema=#Schema(oneOf= {class1.class, class2.class}))) but haven't been able to get it to add the model using that. I also tried adding a dummy class with #ApiModel(subTypes={class1.class, class2.class}. I don't want to add additional endpoints for each object type due to code maintainability.
My question is: is it possible to add the models through annotations while leaving the input type as String?
Here is the relevant code:
#POST
#Path("/{filetype}/new")
#Consumes("application/json")
public Response writeFile(
#ApiParam(required=true, allowableValues = "class1, class2") #PathParam("filetype") String filetype,
#RequestBody(content=#Content(schema=#Schema(oneOf= {class1.class, class2.class}))) String inputFile
) {
return validateFileAndSaveToServer(filetype, inputFile);
}

Swagger Example Post Body From Annotations

Does anyone know if it's possible to create an example post body with pre-populated/default values from Java annotations? My goal is for users to have a working example when viewing a POST endpoint in Swagger UI. Ideally this working example is created from annotations in the code.
For Example on a model object property:
#ApiModelProperty(example = "http://istock.com/my_cool_image")
#JsonProperty("submitted-image-url")
private String submittedImageUrl;
Would produce something like this in Swagger UI (note the example URL shows up in the Model Schema):
The way it appears to be designed, you have to click on Example Value under Data Type for the request/Value textarea to be populated (at least in Swagger 1.5.9).

Categories

Resources