Changing title and description of Swagger UI using Springfox - spring-boot

I am building a Spring Boot application and documenting it using a Swagger UI using the Springfox Swagger UI. I've got everything documented, but want to customize the title and description but can't figure out how. For example, in this image: https://springfox.github.io/springfox/docs/current/images/springfox-swagger-ui.png the title is "Springfox petstore API" and the description is Lorem Ipsum. But in my Swagger UI, both the title and the description say "API Documentation". I have tried using the #SwaggerDefinition annotation, but it does not seem to do anything.

I recommend you to use swagger editor, then you can auto generate Spring Boot server from the API docs, using "Generate Server" option from Top Menu. It is really great for generating an API for the first time.
If you want to set from the YAML you must provide this fields at the info section:
info:
version: "1.0.0"
title: My API title
description: "Awesome description"
From the code, check the generated classes from Swagger editor and compare it with your code. You could set description and title, setting the corresponding attributes on the ApiInfo Builder object, which is inside the class SwaggerDocumentationConfig.
Here you have the code:
#javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2017-10-05T14:03:51.916-03:00")
#EnableSwagger2
#Configuration
public class SwaggerDocumentationConfig {
ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("My API Title")
.description("Awesome description")
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
.termsOfServiceUrl("")
.version("1.0.0")
.contact(new Contact("", "", "contact#contact.com.uy"))
.build();
}
#Bean
public Docket customImplementation() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.mypackage.api"))
.build()
.apiInfo(apiInfo());
}
}
If none of this makes sense to you, show me a little more of your code to know how you are using Springfox and I can help you better.
Bests regards!

Related

Unable to find a model that matches key is shown when spring-boot app is started

I have a spring-boot application with swagger and OpenAPI. Before adding OpenApi the error didn't show, so I assume it must be connected to it. This is the error showing in the logs
[ERROR] Unable to find a model that matches key ModelKey{qualifiedModelName=ModelName{namespace='com.myproject.repository.model', name='ErrorJson'}, viewDiscriminator=null, validationGroupDiscriminators=[], isResponse=true}
This is my bean for the swagger
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.host(hostname)
.select()
.apis(RequestHandlerSelectors.basePackage("com.myproject.repository"))
.paths(PathSelectors.any())
.build()
.securitySchemes(Collections.singletonList(apiKey()))
.securityContexts(Collections.singletonList(securityContext()));
}
If any other information is needed I would be happy to provide it.
Managed to solve the issue by adding this property
springfox.documentation.swagger.use-model-v3: false
Springfox 3.0 uses v3 models by default, but source.getResponses() gives wrong type. To workaround it for now, add: springfox.documentation.swagger.use-model-v3=false in your application.properties.

How I can ignore PathVariable conditionally on swagger ui using springdoc openapi

I am migrating from springfox 2.9.0 to springdoc-openapi-ui 1.2.33.
I have a requirement to show or hide the PathVariable on swagger ui based on condition.
I have two paths like below
String nameIdentifier = "{fisrtName}/{lastName}"
String nameIdentifier = "{fisrtName}"
I am passing one of the above nameIdentifier based on the requirement.
I am using a single controller for the above paths as shown below
#GetMapping(path = "persons/${nameIdentifier}/display")
public List<Person> getPersons(#PathVariable String fisrtName,
#IgnoreLastName #PathVariable Optional<String> lastName) {
}
In springfox I was able to achieve it using docket.ignoredParameterTypes(IgnoreLastName.class) as shown below.
#Bean
public Docket api() {
Docket docket;
docket = new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.basePackage("go.controller")).paths(PathSelectors.any()).build()
.apiInfo(apiInfo());
if (!nameIdentifier.contains("lastName")) {
docket.ignoredParameterTypes(IgnoreLastName.class);
}
return docket;
}
But in springdoc open api I am unable to achieve the same.
Your help appreciated in the same.
Coding is done in java
Thanks
You can use #Hidden swagger annotations or #Parameter(hidden = true).
If you can not pass on parameter level, you can set it globally: You will need to upgrade to v1.3.0 of springdoc-openapi-ui.
static {
SpringDocUtils.getConfig().addAnnotationsToIgnore(IgnoreLastName.class);
}

Springboot, CXF 3.2.7, Swagger2Feature: Authorization header does not appear in the request headers

I'm trying to integrate Swagger 2 into my API, which is implemented with CXF newest version: 3.2.7.
I tried lots of tutorials, the CXF official documentation, others too (e.g. Spring Boot, Apache CXF, Swagger under JAX-RS).
The swagger official website does not help for me. The swagger OpenAPI 2.0 authentication doc is not working, neighter the OpenAPI 3.0.
It is not working with component schemes of Open API 3.0.0, so i stayed with the apiKeyDefinition.
The one, which is working now can be found in this thread, in the answer of #Naoj:
CXF Swagger2Feature adding securityDefinitions
With this solution the swagger ui appeared and also the Autorize button is showing.
I fill the authentication form, and after that, I try to send requests with the swagger-ui. The problem is, that the Authorization header does not appear in the request, so I got 401 response.
In the pom:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-service-description-swagger</artifactId>
<version>3.2.7</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>swagger-ui</artifactId>
<version>3.20.1</version>
</dependency>
My swagger configuration looks like this:
#Configuration
public class SwaggerConfig {
#Bean
#ConfigurationProperties("swagger")
public Swagger2Feature swagger() {
return new ExtendedSwagger2Feature();
}
#Bean
#DependsOn("jaxRsServer")
public ServletContextInitializer initializer() {
return servletContext -> {
BeanConfig scanner = (BeanConfig) ScannerFactory.getScanner();
Swagger swagger = scanner.getSwagger();
servletContext.setAttribute("swagger", swagger);
};
}
}
The extended swagger feature is the following:
#Provider(value = Provider.Type.Feature, scope = Provider.Scope.Server)
public class ExtendedSwagger2Feature extends Swagger2Feature {
#Override
protected void addSwaggerResource(Server server, Bus bus) {
super.addSwaggerResource(server, bus);
BeanConfig config = (BeanConfig) ScannerFactory.getScanner();
Swagger swagger = config.getSwagger();
swagger.securityDefinition("Bearer", new ApiKeyAuthDefinition("authorization", In.HEADER));
}
}
I try to configure Bearer JWT token based authentication. My application.yml contains the following:
swagger:
basePath: /rest
title: Backend Application
description: Swagger documentation of Backend Application REST services
license:
licenceUrl:
contact:
resourcePackage: my.resource.package
scan: true
apiKeyAuthDefinition:
name: Authorization
in: header
type: http
I import the SwaggerConfig into my #SpringBootApplication class like this:
#Import(SwaggerConfig.class)
It is working, as i see, swagger appeared and the title and description field is filled with the properties of my yml.
What am I missing? Any suggestions would be appretiated.
Thanks in advance.
You can simplify your code and remove ExtendedSwagger2Feature and the initializer(). Modify your swagger() method as follows and the output will be the same:
#Bean
#ConfigurationProperties("swagger")
public Swagger2Feature swagger() {
Swagger2Feature swagger2Feature = new Swagger2Feature();
swagger2Feature.setSecurityDefinitions(Collections.singletonMap("bearerAuth",
new ApiKeyAuthDefinition("Authorization", In.HEADER)));
return swagger2Feature;
}
The reason for the token not being added to your request, is that securityDefinitions is just a declaration for the available schemes. You need to apply it to the operation by adding (to your TestResource interface):
#Api( authorizations = #Authorization( value = "bearerAuth" ))
You will notice a lock icon next to the operation in Swagger UI. Currently it's not there.
Btw. you should use the newer OpenApiFeature instead of the old Swagger2Feature. Happy to answer questions, if you have problems with it.

Swagger 2.0 support in Grails 3+ (3.0.11) not working

I am running Grails 3.0.11 and want to create Swagger-documentation for my REST endpoints. I added the SwaggyDoc-plugin to the dependencies in my build.gradle script by adding:
compile "org.grails.plugins:swaggydoc:0.26.0".
In IntelliJ I see the Swaggydoc-dependency added to my list of libraries.
After starting my Grails-application via the grails run-app command and opening my application by entering http://localhost:8080/api/ I get an 404 error telling the page does not exist.
Do I need to configure something more or to run something special to generate documentation? I already tried to open a ticket in the Git-project and contacting the author with no succes.
Update1: there seems to be a Grails 3-plugin (found at Versioneye?) which I added:
compile "org.grails.plugins:swaggydoc-grails3:0.26.0"
It does work half, by default some sort of Pet-demo is visible and it is failing on constraints in a domain and enums. Doesn't seem to work very well actually.
Update2: As pointed out by Dilip Krishnan I tried to use SpringFox, first I added the dependencies to my Gradle build file:
compile("io.springfox:springfox-swagger2:2.3.1")
compile("io.springfox:springfox-swagger-ui:2.3.1")
Then I added a new class called ApiDocumentationConfiguration with the following code:
#Configuration
#EnableSwagger2
public class ApiDocumentationConfiguration {
#Bean
public Docket documentation() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
#Bean
public UiConfiguration uiConfig() {
return UiConfiguration.DEFAULT;
}
private ApiInfo metadata() {
return new ApiInfoBuilder()
.title("My awesome API")
.description("Some description")
.version("1.0")
.contact("my-email#domain.org")
.build();
}
}
My Grails resources file contains the following code:
beans = {
apiDocumentationConfiguration(ApiDocumentationConfiguration)
}
Last step was starting the application and trying to load the end point which shows the Swagger front end:
http://localhost:8080/swagger-ui.html
It behind the scenes tries to load an other end point (containing the JSON I guess?) which loads
http://localhost:8080/v2/api-docs
This does show JSON data and I get end points for things like a basic error controller, health mvc, metrics mvc et cetera. But not my own annotated user controller which is annotated like follows:
#Api(value = "users", description = "Endpoint for user management")
class UserController {
// GET all users
#ApiOperation(value = "doStuff", nickname = "doStuff", response = User.class)
def index() {
respond User.list()
}
}
Seems I am almost there, but still missing something, is my annotation wrong or doesn't it scan my controllers?
Update3: in contact with one of the authors of SpringFox (Dilip Krishnan) to add support for Grails 3+ to SpringFox, see ticket. The reason it doesn't currently work is because SpringFox looks at MVC annotation, an adapter needs to be written to retrieve the endpoints from the controllers in Grails.
I have successfully used swaggydocs in both 2.4.x projects and 3.1.4.
In order to make it work in 3.x (tested on 3.1.4) you have to add
compile "org.grails.plugins:swaggydoc-grails3:0.26.0"
to gradle dependencies section. That makes swaggy available in your project.
Then add annotations to your controllers
#Api("test methods")
class TestController {
#ApiOperation(value = "some method description")
#ApiResponses([
#ApiResponse(code = 405, message = "Bad method. Only POST is allowed"),
#ApiResponse(code = 401, message = "Unauthorized"),
#ApiResponse(code = 400, message = "Invalid request json")
])
def testGetMethod() {
render([status: "OK"] as JSON)
}
Then mark your methods allowedMethods as follows
class TestController {
static allowedMethods = [testGetMethod: "GET", testPostMethod: "POST"]
NOTE this is really important - otherwise swaggy will mark every your method as GET. Swaggy doesn't respect neither httpMethod in ApiOperation annotation nor http method in url mappings.
Finally add your controller to urlmappings as swaggy checks url mappings to look for URLS. Note camelCase!
//NOTE small camelCase
//swaggy won't see urls correctly if you start controller name with capital letter
"/api/test/"(controller: "test", action: "testGetMethod")
"/api/test/"(controller: "test", action: "testPostMethod")
You can also add some api info in application.yml
swaggydoc:
contact: rafal#pydyniak.pl
description: sample swaggy app
You can find sample app (with dummy methods but point was to make swaggy work) at my github https://github.com/RafalPydyniak/Swaggy-example.
Also there are some more docs on how to use this api on http://rahulsom.github.io/swaggydoc/. I just wanted to show you how to install it (as it's quite tricky to make everything work)
Hope it helps!
I followed the same 2 steps:
1) add swagger2 dependencies
2) provide configuation
The problem is that sprinfox does not scan grails url mappings (see https://github.com/springfox/springfox/issues/1169#issuecomment-252259284)
To fix that I added standard spring annotations:
#Controller()
#RequestMapping(value="/path")
on the controller and
#RequestMapping(value="/resource")
on the method. After that sprinfox started to pick up my documentation.

Springfox not generating Swagger docs correctly for same operation-endpoint, different query parameters

Springfox doesn't generate correctly the swagger doc for a simple case like this one:
GET /api/departments - Gets all department
GET /api/departments?name=IT - Gets a department with name passed as query parameter
This is the Spring Controller:
#ApiOperation(value = "Gets all departments", notes = "", tags = {"departments"})
#RequestMapping(value="/departments", produces=MediaType.APPLICATION_JSON_VALUE, method=RequestMethod.GET)
public List<Department> getAllDepartments(){
...
}
#ApiOperation(value = "Gets a department by name", notes = "", tags = {"departments"})
#RequestMapping(value="/departments", params="name", produces=MediaType.APPLICATION_JSON_VALUE, method=RequestMethod.GET)
public Department getDepartmentByName(#RequestParam String name){
...
}
The generated swagger file only contains the GET /api/departments entry, not a trace of the one with the query filter.
Any workaround?
Swagger Config:
#Bean
public Docket departmentsV1Api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.regex("/.*"))
.build()
.apiInfo(new ApiInfo("Departments Rest API","","v1","","","",""))
.pathMapping("/api")
.securitySchemes(newArrayList(apiKey()))
.securityContexts(newArrayList(securityContext()))
.groupName("departmentsV1");
}
This use case isn't supported by the spec. However you could use the enableUrlTemplating(true) method in your docket to enable rfc6570 support.
There is also an experimental library (springfox-swagger-ui-rfc6570) that can be used as a drop-in replacement for the standard springfox-swagger-ui.
Note: Keep in mind this is in incubation and can change when support is added in the spec.

Resources