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

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.

Related

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);
}

How can we change the default Swagger URL to any other

I have integrated Swagger into my Spring Boot Application. I am able to view the documentation created for a single Controller class , on the default swagger URL i.e - http://localhost:8081/swagger-ui.html#/
How can we change '/swagger-ui.html/' path to any other Custom path .
Also adding the code snippet. I want the url to be like :
http://localhost:8081/swagger#/
#Bean
public Docket usersApi(ServletContext servletContext){
return new Docket(DocumentationType.SWAGGER_2).pathProvider(new RelativePathProvider(servletContext){
#Override
public String getApplicationBasePath() {
return "/swagger" + super.getApplicationBasePath();
}
})
.apiInfo(apiInfo())
.select()
.paths(PathSelectors.regex("/api/v1/.*" ))
.build();
}
Thanks in Advance

Changing title and description of Swagger UI using Springfox

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!

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