Swagger 2.0 offline validation - validation

I know that there's a tool that is able to do an online validation:
http://online.swagger.io/validator?url=http://petstore.swagger.io/v2/swagger.json
I'm writing a JUnit test that validates the project's swagger.json file. It's important that this validation can be done offline, because the test runs as localhost, and that validation tool can't reach a localhost server.
So, is it possible to validate a Swagger 2.0 JSON file, offline?

I'm very satisfied with this Validator from Atlassian: https://bitbucket.org/atlassian/swagger-request-validator
There is still active development, so I guess they will also provide something for OpenAPI 3.

I have created a Maven project that validates swagger JSON documents if you ever decide to use Maven for running your tests.
You can clone the project here: https://github.com/navidsh/maven.swagger.validator

Well, I finished a Swagger validator using fge/json-schema-validator and Jackson. It uses the Swagger 2.0 schema to validate.
https://gist.github.com/mariosotil/e1219d4e946c643fe0e5
#Singleton
public class SwaggerValidator {
public ArrayNode validate(JsonNode jsonNode) {
return Optional.of(jsonNode)
.map(this::validateWithinSwaggerSchema)
.map(this::getMessagesAsJsonArray)
.get();
}
// [...]
}

Related

Spring boot, tomcat, rest api 404

I am using Kotlin + Gradle and trying to build a war file to deploy on Tomcat. My application is from the https://start.spring.io plus a simple controller and build the war file using ./gradlew bootWar
#SpringBootApplication
class ServletInitializer : SpringBootServletInitializer() {
override fun configure(application: SpringApplicationBuilder): SpringApplicationBuilder {
return application.sources(DemoApplication::class.java)
}
}
#RestController
class TomcatController {
#GetMapping("/hello")
fun sayHello(): Collection<String> {
return IntStream.range(0, 10)
.mapToObj { i: Int -> "Hello number $i" }
.collect(Collectors.toList())
}
}
when I try to access it I get
Type Status Report
Message The requested resource [/demo-0.0.1-SNAPSHOT/hello] is not available
Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
I am super stuck. What am I doing wrong? If I add a html file to the src/main/webapp/index.html it shows up for some reason only the rest api can't be reached.
Spring Boot applications come with a built in Servlet. You are probably already using this feature when launching the application inside your IDE.
This basically means that you can just run your .jar file on any web server and it will be ready to go without setting up an extra tomcat instance.
However, if you want to build a Spring Boot application as a war file and deploy it to an external tomcat, you need to follow some extra steps as explained in this article.
Assuming from what you posted so far: the path that is returned shows another route before your actual controller route "/demo-0.0.1-SNAPSHOT/hello" is this "/demo-0.0.1-SNAPSHOT" the path that your application runs on ? If not it should be included in your controller (assuming you havent set it elsewhere for e.g. in your application.properties).
for e.g. http://localhost:8080/ would be the basepath and either http://localhost:8080/demo-0.0.1-SNAPSHOT/hello or http://localhost:8080/hello would point to your controller. Also your startup logs (for Tomcat and Spring) might give away more about the issue.

How to upload with ExpediaGroup's graphql-kotlin?

There's nothing related to file upload in the examples under https://github.com/ExpediaGroup/graphql-kotlin/tree/master/examples/server/spring-server/src/main/kotlin/com/expediagroup/graphql/examples/server/spring.
I'd like to upload 5 files at once and although I think it should be a mutation I'm not sure whether it should go like this:
class UploadMutation: Mutation {
fun upload(files: FilePart) {
print("$files")
}
}
The context is obviously Spring Boot with Kotlin and WebFlux.
According to the developers they don't support Apollo-like file uploads at all.
File uploads can be built using our library and spring boot, but they are not included out of the box. You will have to configure the response parser yourself
https://github.com/ExpediaGroup/graphql-kotlin/discussions/1037

Spring-Doc open api not working with Spring cloud config server #EnableConfigServer

Im using spring boot 2.3.2.RELEASE with spring-cloud-config-server 2.2.4.RELEASE. Im trying to implement the spring-doc-openapi (1.4.3) in a existing project. If i add #EnableConfigServer in one the configuration class file, the swagger-ui.html endpoint returns a weird json:
"name":"swagger-ui",
"profiles":[
"index.html"
],
"label":null,
"version":null,
"state":null,
"propertySources":[
]
}
and not the the swagger ui as expected. Im not sure if its a bug, but would appreciate any kind of help.
Not sure if its relevant to add the springdoc dependency on spring cloud config server, unless you need to explore some APIs on the config server it self.
Here is the link of a fully working example using springdoc with config server:
https://github.com/springdoc/springdoc-openapi-demos/tree/master/sample-springdoc-openapi-microservices
And this is the link of a blog which explains the natural usage with microservies and spring cloud modules:
https://piotrminkowski.com/2020/02/20/microservices-api-documentation-with-springdoc-openapi/
Answer from #brianbro seems not to be working anymore...
Verified on: springdoc-openapi v1.6.6 and org.springframework.cloud:spring-cloud-config-server:v2.2.4.RELEASE
Here is how I solved it:
List item spring.cloud.config.server.prefix=config-server - please note that any request to config server will require to add prefix!
Add following bean (sample implementation in Kotlin)
#Bean fun configServerApi(): GroupedOpenApi =
GroupedOpenApi.builder()
.group("Config server")
.pathsToMatch(
"/config-server/**"
)
.build()
Now you should be able to reach swagger ui :)

Quarkus : Change OpenApi authorization url at runtime

I am currently experimenting with quarkus and cannot find a way to change some openapi information at runtime (here, I want the authorization url to change depending on the environment).
It should be possible by using OASFilter and feeding information from environment variables but OASFilter seems to be initialized at build time. I added a log in the filterSecurityScheme method and the log is displayed at build (by quarkus-maven-plugin) and then never displayed at runtime.
The code is pretty simple :
public class OASSecurityConfiguration implements OASFilter {
#Override
public SecurityScheme filterSecurityScheme(final SecurityScheme securityScheme) {
securityScheme.getFlows().
getImplicit().
setAuthorizationUrl(ConfigProvider.getConfig().getValue("quarkus.oidc.auth-server-url", String.class)+"/protocol/openid-connect/auth");
return securityScheme;
}
}
Is there any other way to change openapi specs at runtime from environment variables or to prevent the OASFilter to be initialized at build time ?
Thanks.
Since Quarkus v2 there is now a config option quarkus.smallrye-openapi.always-run-filter (docs) that enables you to run the OASfilter everytime the openapi document is served.

generate sample example in swagger UI (in Spring boot project)

I am using a spring boot application and have configured using Swagger UI.
I want to know whether we could pre-populate the example value with sample value so we can hit the "Try it out!" button without having to type in some sample values to get a response.
It must be present there.
Is there a way we can do this using annotations or a separate file which Swagger uses?
I am using a spring boot project with springfox-swagger2:2.7.0 and springfox-swagger-ui:2.7.0 with dependencies added using gradle.
Since the #ApiParam properties example and examples are not working (see this issue on GitHub), support for adding examples is limited/non existing.
What you can do for simple parameters (#RequestParam) is to add the #ApiParam annotation with the defaultValue property, like this:
#GetMapping
public List<Foo> findAll(
#RequestParam(required = false)
#ApiParam(defaultValue = "foo") // Put the default value here
String input) {
// ...
}
However, there is no support yet for doing this with #RequestBody parameters.
A possible workaround for #RequestBody parameters is by clicking on the code box at the right side of the Swagger tester, where it says Example value. If you click on it, it will insert that example into the field itself.
Here is a workaround for providing an example:
Inject html into swagger
#ApiParam(
name="whatever",
value="whatever",
defaultValue="none</p><p>Example: xyz</p>"
)
They don't protect against it in the latest version 2.9.2.

Resources