Swagger based validation

Posted by Ram R on October 17, 2021
     

These days Swagger/OpenAPI is commonly used to document Restful APIs or  Lambda Micro-services. A .yaml  or .json file containing an  OpenAPI definition of the API under development is used for stub creation & documentation among other things.

The same definition file can be used to create an input request validation layer within the service using Atlassian’s swagger-request-validator library

The client  consuming the API will send the request & the library will use the OpenAPI definition to validate either the request body or form parameters depending upon the use case.  Here, I have provided a Kotlin example to validate a request body with the library.

                
import com.atlassian.oai.validator.OpenApiInteractionValidator
import com.atlassian.oai.validator.model.SimpleRequest
import org.slf4j.LoggerFactory
                   
const val mySwaggerSpecFileName = "myservice-swagger.yaml"
                   
object ValidationUtils {
                   
  private val logger = LoggerFactory.getLogger(ValidationUtils::class.java)
  private val myValidator = OpenApiInteractionValidator.createFor(mySwaggerSpecFileName ).build()
                   
  fun swaggerSpecValidate(
    path: String,
    body: String?,
    headers: MutableMap?
  ){
      val startTime = System.currentTimeMillis()
      logger.debug("Validation start time: $startTime")
                   
      val request = SimpleRequest.Builder.post(path).withBody(body)
      if ( headers != null )
        headers.forEach { name, value -> request.withHeader(name, value) }
                    
      logger.debug("Request headers :$headers")
      val validationReport = myValidator.validateRequest(request.build())
      logger.debug("Duration: ${System.currentTimeMillis() - startTime}
  }")
                   
  if (validationReport.hasErrors()) {
    validationReport.messages.forEach { logger.debug("Input Validation Error: $it") }
    val errorCode =  ErrorConstants.InvalidJSONRequest 
    throw MyServiceException(
      errorCode,
      listOf(ErrorDetails("Swagger", validationReport.messages.joinToString(), "", ""))
    )
  }
}                                    
                
              

 

In the above example, The OpenAPI definition can be passed as

  1. A http url
  2. A file location on the server using file:// prefix
  3. A file-name provided the file exists on project classpath & finally
  4. A string payload in json format.

Please note, a pre-requisite for the library is that “Content-type” header needs to be present in the request else it spits out an empty validation report. A validation report will generally contain all the errors that the Swagger Spec/OpenAPI definition identifies in the request body or query string.

A service response can also be validated in a similar manner.