Validate your specs with OpenAPI Style Validator
Tags: openapi, java
Published: 2023-04-28 14:24:12

OpenAPI Style Validator is a tool to create API specs with understandable descriptions, examples and consistent use of naming conventions. 

The Validator helps developers to identify issues in OpenAPI specifications. With defined rules you can describe exactly how an API specification should look. These specs can be checked automatically and the results can be used in code reviews or even in a build pipeline where rule violations result in a build break.

**Complete descriptions and naming conventions**
The validator checks various objects of the OpenAPI schema, starting with the info object and the associated contact and license object. Often these details are not provided at all. Here you see as an example how the popular Petstore example provides the details.

```javascript 
{
"info": {
    "version": "1.0.0",
    "title": "Swagger Petstore",
    "description": "A sample API that uses a petstore as an example to demonstrate features in the OpenAPI 3.0 specification",
    "termsOfService": "http://swagger.io/terms/",
    "contact": {
      "name": "Swagger API Team",
      "email": "apiteam@swagger.io",
      "url": "http://swagger.io"
    },
    "license": {
      "name": "Apache 2.0",
      "url": "https://www.apache.org/licenses/LICENSE-2.0.html"
    }
  }
}
```

The next object we'll take a closer look at is the operation object. But let's start with the paths object. The paths object contains all the paths to existing endpoints (path items). A single path (/pets) contains operations which describe what http methods are allowed. 

```javascript 
{
"/pets/{id}": {
    "get": {
      "description": "Returns a user based on a single ID, if the user does not have access to the pet",
      "operationId": "find pet by id",
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "description": "ID of pet to fetch",
          "required": true,
          "schema": {
            "type": "integer",
            "format": "int64"
          }
        }
      ],
    }
   }
}
```

The OpenAPI Style Validator detects whether certain properties exist For example, the property "summary" is missing in the above listing. In contrast, a "description" is present. The absence of a property is an error, if you have configured it that way.

Let's look how the OpenAPI Style Validator checks the data type descriptions. Data types are defined in the OpenAPI specification as schema objects that can be referenced in requests or responses (e.g. "$ref": "#/components/schemas/NewPet"). The validator can check if all schema properties like description and example are present and not empty.

```javascript 
{
"NewPet": {
    "type": "object",
    "required": [
      "name"
    ],
    "properties": {
      "name": {
        "type": "string"
      },
      "tag": {
        "type": "string"
      }
    }
  },
}
```

If we look at the NewPet schema object in the above listing, we do not find descriptions and examples. Examples and descriptions in an API spec make the documentation more understandable.

Now let's move on to naming conventions. Naming conventions help to make an API easier to use. The OpenAPI Style Validator supports a number of different conventions that we can apply to paths, path parameters, query parameters, cookies, headers and properties. The naming conventions are: the underscore case (snake_case), camel case as we know it from Java and JavaScript and the so called hyphen case, also known as Kebab Case.

**Options and launching the OpenAPI Style Validator**
With the defined rules we have learned now, we can control how an OpenAPI specification has to look. What kind of options do we have? There are boolean options like "validateOperationOperationId", which by a true, requires that each operation has an id. The option "validateOperationSummary" requires that operations also have a description. But there are also string type options like pathNamingConvention, parameterNamingConvention, pathParamNamingConvention and queryParamNamingConvention. With these options, we can determine if elements should follow e.g. the underscore case or camel case naming convention.

So, how do we launch the validator? The maven command looks like this:

```
mvn openapi-style-validator:validate
```

For Maven the OpenAPI Style Validator plugin must be configured inside the pom.xml Currently, io.swagger.core.v3 dependency must be excluded, otherwise a newer version of the library is used which unfortunately is incompatible with version 1.8 of the OpenAPI Style Validator. As you can in the following listing, each option can be added as a parameter under an XML tag, e.g. "validateOperationSummary" with true or false as text content.

```
<plugin>
<groupId>org.openapitools.openapistylevalidator</groupId>
<artifactId>openapi-style-validator-maven-plugin</artifactId>
<version>1.8</version>
<configuration>
    <inputFile>petstore-expanded.json</inputFile>
</configuration>
<dependencies>
    <dependency>
        <groupId>org.openapitools.empoa</groupId>
        <artifactId>empoa-swagger-core</artifactId>
        <version>2.0.0</version>
        <exclusions>
            <exclusion>
             <groupId>io.swagger.core.v3</groupId>
                <artifactId>swagger-models</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>
</plugin>
```

And by the way, with the default configuration we get the following result for the Petstore example:

```
[INFO] --- openapi-style-validator:1.8:validate (default-cli) @ openapitools-validator-mvn-example ---
[INFO] Validating spec: petstore-expanded.json
[ERROR] OpenAPI Specification does not meet the requirements. Issues:

[ERROR]         *ERROR* in Operation GET /pets "summary" -> This field should be present and not empty
[ERROR]         *ERROR* in Operation GET /pets "tags" -> The collection should be present and there should be at least one item in it
[ERROR]         *ERROR* in Operation POST /pets "summary" -> This field should be present and not empty
[ERROR]         *ERROR* in Operation POST /pets "tags" -> The collection should be present and there should be at least one item in it
[ERROR]         *ERROR* in Operation GET /pets/{id} "summary" -> This field should be present and not empty
[ERROR]         *ERROR* in Operation GET /pets/{id} "tags" -> The collection should be present and there should be at least one item in it
[ERROR]         *ERROR* in Operation DELETE /pets/{id} "summary" -> This field should be present and not empty
[ERROR]         *ERROR* in Operation DELETE /pets/{id} "tags" -> The collection should be present and there should be at least one item in it
[ERROR]         *ERROR* in Model "NewPet", property "name", field "example" -> This field should be present and not empty
[ERROR]         *ERROR* in Model "NewPet", property "name", field "description" -> This field should be present and not empty
[ERROR]         *ERROR* in Model "NewPet", property "tag", field "example" -> This field should be present and not empty
[ERROR]         *ERROR* in Model "NewPet", property "tag", field 'description' -> This field should be present and not empty
[ERROR]         *ERROR* in Model "Error", property "code", field 'example' -> This field should be present and not empty
[ERROR]         *ERROR* in Model "Error", property "code", field 'description' -> This field should be present and not empty
[ERROR]         *ERROR* in Model "Error", property "message", field "example" -> This field should be present and not empty
[ERROR]         *ERROR* in Model "Error", property "message", field "description" -> This field should be present and not empty
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.342 s
```

**Links**
[OpenAPI Style Validator](https://github.com/OpenAPITools/openapi-style-validator)
[Petstore Beispiel](https://github.com/OAI/OpenAPI-Specification/blob/main/examples/v3.0/petstore-expanded.json
)
[Validation example](https://bit.ly/3HoiW77)

Photo by [Yassine Khalfalli](https://unsplash.com/@yassine_khalfalli?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText") on [Unsplash](https://unsplash.com/photos/I3ZzOkiAbTI?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)