<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Jakub Vacek</title>
    <description>The latest articles on Forem by Jakub Vacek (@jakubvacek).</description>
    <link>https://forem.com/jakubvacek</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F675013%2F3f526407-2d0e-43a6-b263-bbe6dd6ab8e6.jpeg</url>
      <title>Forem: Jakub Vacek</title>
      <link>https://forem.com/jakubvacek</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jakubvacek"/>
    <language>en</language>
    <item>
      <title>Power-up your OpenAPI Spec in 13 steps</title>
      <dc:creator>Jakub Vacek</dc:creator>
      <pubDate>Thu, 29 Sep 2022 15:10:49 +0000</pubDate>
      <link>https://forem.com/superface/power-up-your-openapi-spec-in-13-steps-5dbm</link>
      <guid>https://forem.com/superface/power-up-your-openapi-spec-in-13-steps-5dbm</guid>
      <description>&lt;p&gt;During my work on &lt;a href="https://superface.ai/blog/integration-designer-announcement" rel="noopener noreferrer"&gt;Superface Integration Designer&lt;/a&gt;, I used numerous OpenAPI Specification (OAS) files describing the APIs of some well known service providers. The quality of these specifications varies heavily, and if you decide to use them as input for some tool, you can end up with poor results. The poor quality of OAS files was frustrating for me, so I decided to write down the most common issues I ran into. The list is primarily focused on OpenAPI Specification, but most of the suggestions are applicable to other specification formats, and also touch upon API design.&lt;/p&gt;

&lt;p&gt;Let's assume that you write an API specification. Why should you think about automated processing of your API specification? Because you will benefit from it in the long run. There is &lt;a href="https://openapi.tools" rel="noopener noreferrer"&gt;a growing number of tools that use OpenAPI Specification&lt;/a&gt; as input, and allow you to do things like validation, SDK code generation, API mocking, automated security checks, and more. If you build APIs, take a look at them. It could change the way you look at the role of API specification in your development process.&lt;/p&gt;

&lt;p&gt;There is a common misconception that people create API specification for other people to read. Specification writers can then take shortcuts. Shortcuts lead to lower quality of API specification which, in the end, results in subpar output of tools processing your API specification.&lt;/p&gt;

&lt;p&gt;Let’s look at the most common errors that complicate OAS documents use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Play safe with versions
&lt;/h2&gt;

&lt;p&gt;Use well established versions of OpenAPI Specification which are supported by automated processing tools. By using an established OAS version, you give your users a larger variety of tools compatible with your specification.&lt;/p&gt;

&lt;p&gt;As of September 2022, the majority of tools supports OAS version 3.0, but not every tool supports OAS 3.1 or 2.0. When in doubt, check the &lt;a href="https://openapi.tools" rel="noopener noreferrer"&gt;list of tools&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep your API simple
&lt;/h2&gt;

&lt;p&gt;This one is more connected to API design, but I consider this significant enough to be mentioned. When designing your API, keep in mind that you need to be able to describe it with OAS. So think twice before using non-standard security schemes or obscure request/response types.&lt;/p&gt;

&lt;p&gt;For example, in one of the OAS documents we tested an endpoint that accepted either a string or an object with properties, and returned the same type based on the request contents. This kind of relationship between the request and the response is not possible to describe in OpenAPI Specification. The tool processing this specification has no way to connect the request schema with the appropriate response schema.&lt;/p&gt;

&lt;h2&gt;
  
  
  Describe everything, but keep it short
&lt;/h2&gt;

&lt;p&gt;OAS document doesn't replace documentation, but complements it. It's a reference where each entity should be sufficiently documented, but shouldn't contain marketing language or information that isn’t directly needed to use the API. Tutorials, guides, and use cases belong to dedicated documents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Provide a sandbox server
&lt;/h2&gt;

&lt;p&gt;In the OpenAPI Specification, &lt;code&gt;servers&lt;/code&gt; represents an array of objects with information on how to connect to different instances of the API. These can be, for example, production and staging servers. If all endpoints in your API require authorization, provide a sandbox service which operates on dummy data. This allows a user to quickly try out your API in their project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Specify security
&lt;/h2&gt;

&lt;p&gt;Define all security schemes and connect each endpoint to the correct scheme. Every scheme should describe how to obtain the key or authorize (or link to the documentation). Many OAS documents define multiple global security schemes, but don’t specify which endpoint uses which security scheme.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the naming consistent
&lt;/h2&gt;

&lt;p&gt;Use names that are descriptive and clear, avoid mixing different naming conventions (like camelCase, snake_case, and kebab-case). Avoid property names or enums starting with non-alphabetic characters (like numbers or dashes) as these can lead to issues during automated processing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;object&lt;/span&gt;
    &lt;span class="c1"&gt;# DO NOT DO THIS:&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;accountName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
        &lt;span class="na"&gt;account_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
        &lt;span class="na"&gt;account-description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
        &lt;span class="na"&gt;3h&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;number&lt;/span&gt;
        &lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
            &lt;span class="na"&gt;enum&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;-start_at&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;+start_at&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Enumerate all property types
&lt;/h2&gt;

&lt;p&gt;When it comes to defining the data schema and property types, be as precise as possible. Don’t forget to cover whether an endpoint accepts multiple types, for example string and &lt;code&gt;null&lt;/code&gt;. This information is crucial for the quality of the generated output. This is the most common problem I have encountered. When you generate an SDK from such an incorrectly described OAS document, the client code doesn't expect the value to be nullable, which will cause errors.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;object&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;foo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Works in OAS 3.1&lt;/span&gt;
            &lt;span class="c1"&gt;# foo can be string or null&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;string'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;null'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
        &lt;span class="na"&gt;bar&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Works in OAS 3.0&lt;/span&gt;
            &lt;span class="c1"&gt;# bar can be string or null&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
            &lt;span class="na"&gt;nullable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Mark required properties
&lt;/h2&gt;

&lt;p&gt;Make sure to correctly mark required properties. Ignoring the &lt;code&gt;required&lt;/code&gt; property is another common mistake which affects validation and mocking tools.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;object&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;foo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
        &lt;span class="c1"&gt;# bar can be undefined&lt;/span&gt;
        &lt;span class="na"&gt;bar&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;foo'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Don't forget errors
&lt;/h2&gt;

&lt;p&gt;List all the error responses with correct status codes and response bodies, provide example errors, follow HTTP status code definitions. OpenAPI Specification allows multiple ways to define error response. You can use the &lt;code&gt;default&lt;/code&gt; response, or wildcard response &lt;code&gt;4xx&lt;/code&gt; as described in the &lt;a href="https://swagger.io/specification/#responses-object" rel="noopener noreferrer"&gt;Specification&lt;/a&gt;. Error responses are vital when you are using the specification with a tool for mocking responses.&lt;/p&gt;
&lt;h2&gt;
  
  
  Add examples
&lt;/h2&gt;

&lt;p&gt;You should provide a valid example for each parameter. These examples are useful for API mocking and SDK generation tools, as they can be used as mock values.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;object&lt;/span&gt;
    &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;temp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;number&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Temperature&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;in&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;kelvin"&lt;/span&gt;
      &lt;span class="na"&gt;example&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;293.25&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;-- example value&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Weather&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;condition&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;within&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;group"&lt;/span&gt;
      &lt;span class="na"&gt;example&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;broken&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;clouds"&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;-- example value&lt;/span&gt;
        &lt;span class="na"&gt;country&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Country&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;code&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(GB,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;JP&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;etc.)"&lt;/span&gt;
      &lt;span class="na"&gt;examples&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
             &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;AU&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;-- first example value&lt;/span&gt;
             &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CZ&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;-- second example value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Define default values
&lt;/h2&gt;

&lt;p&gt;For optional properties, make sure to specify a default value if there is one. Similar to examples, this is useful for tools and documentation purposes.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
    &lt;span class="na"&gt;enum&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;json&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;xml&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;html&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;json"&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;-- default value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Detail property format
&lt;/h2&gt;

&lt;p&gt;In addition to &lt;code&gt;type&lt;/code&gt;, you can also specify the &lt;code&gt;format&lt;/code&gt; of the value, for example &lt;code&gt;int32&lt;/code&gt;, &lt;code&gt;date-time&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt;. You can also specify a regular expression. The full list of possible values can be found in the &lt;a href="https://json-schema.org/understanding-json-schema/reference/generic.html" rel="noopener noreferrer"&gt;JSON schema specification&lt;/a&gt;. This is useful both for validation and mocking tools.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;integer&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;City ID&lt;/span&gt;
    &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;int32&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;--&lt;/span&gt;
    &lt;span class="na"&gt;example&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2172797&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Use a linter
&lt;/h2&gt;

&lt;p&gt;You can automate most of these checks by using an OpenAPI Specification linter. There are many linters out there, although most of them just validate OAS documents with a prepared JSON Schema. Our &lt;a href="https://github.com/superfaceai/openapi-linter" rel="noopener noreferrer"&gt;OpenAPI Linter&lt;/a&gt; takes a different approach, it uses the Spectral linter with a custom set of rules. These rules were designed to validate OAS documents intended for use with automatic processing tools.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/superfaceai" rel="noopener noreferrer"&gt;
        superfaceai
      &lt;/a&gt; / &lt;a href="https://github.com/superfaceai/openapi-linter" rel="noopener noreferrer"&gt;
        openapi-linter
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Is your OpenAPI Spec ready for SDK generators?
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;OpenAPI Linter&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/superfaceai/openapi-linter/actions/workflows/main.yml" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fbd09ebc431b032fe0f121018653b0649353e1fdf132b899819cdf4009ac9116/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f73757065726661636561692f6f70656e6170692d6c696e7465722f4349" alt="GitHub Workflow Status"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/@superfaceai/openapi-linter" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b60702aeb8c06d3fbfffab422bcf9d1262b9d53b16867c24e4ae45c7074fa7fb/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f4073757065726661636561692f6f70656e6170692d6c696e746572" alt="npm"&gt;&lt;/a&gt;
&lt;a href="https://github.com/superfaceai/openapi-linterLICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/aecd03425f0c732fc77d152de91febe53a0cc65a353b79d8ae8c319a799b4d5f/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f6c2f4073757065726661636561692f6f70656e6170692d6c696e746572" alt="license"&gt;&lt;/a&gt;
&lt;a href="https://oclif.io" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1d19284d17a229e35cda164ad5159b2a3d01619e7dda662df843e74f1a8c8d38/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636c692d6f636c69662d627269676874677265656e2e737667" alt="CLI built with oclif"&gt;&lt;/a&gt;
&lt;a href="https://github.com/orgs/superfaceai/discussions" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/3ace67f1d928ceb0de3482d07149f4304e5b8c1c4a4ccb83bbfd8094b9392bf5/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f64697363757373696f6e732f73757065726661636561692f2e6769746875623f6c6f676f3d676974687562266c6f676f436f6c6f723d666666" alt="GitHub Discussions"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Is your OpenAPI Spec ready for SDK generators?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;OpenAPI Linter is a CLI and a Node.js library to validate OpenAPI specification
It is based on &lt;a href="https://stoplight.io/open-source/spectral" rel="nofollow noopener noreferrer"&gt;Spectral&lt;/a&gt; by Stoplight with &lt;a href="https://meta.stoplight.io/docs/spectral/4dec24461f3af-open-api-rules" rel="nofollow noopener noreferrer"&gt;OpenAPI rules&lt;/a&gt; with additional rules. The goal of Linter is to check whether the spec contains enough information to generate high quality, well documented SDK
We use OpenAPI Linter in &lt;a href="https://superface.ai/designer" rel="nofollow noopener noreferrer"&gt;Superface Integration Designer&lt;/a&gt;, but any client code generator benefits from well written OpenAPI specs.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Setup&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Install from npm globally:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm i -g @superfaceai/openapi-linter&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Now you can use the linter with commands &lt;code&gt;openapi-linter&lt;/code&gt; or &lt;code&gt;oal&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Alternatively you can use the linter without installation with &lt;code&gt;npx&lt;/code&gt;:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;npx @superfaceai/openapi-linter lint &amp;lt;file or URL&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;CLI commands&lt;/h2&gt;

&lt;/div&gt;
  
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/superfaceai/openapi-linter#openapi-linter-lint-specificationpath" rel="noopener noreferrer"&gt;&lt;code&gt;openapi-linter lint SPECIFICATIONPATH&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;&lt;code&gt;openapi-linter lint SPECIFICATIONPATH&lt;/code&gt;&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Lints OpenAPI specification using three different parsers/validators.&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;
&lt;pre class="notranslate"&gt;&lt;code&gt;USAGE
  $ openapi-linter lint [SPECIFICATIONPATH] [-f yaml|json] [-e error|warning|any]
ARGUMENTS
  SPECIFICATIONPATH  Path or URL to specification file

FLAGS
  -e, --throwOn=&amp;lt;option&amp;gt;     [default:&lt;/code&gt;&lt;/pre&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/superfaceai/openapi-linter" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;





&lt;p&gt;In the list above, I highlighted parts of the specifications that are often neglected, but play an important role in automatic processing tools. Focus on these parts, so your specification is useful both for users and automatic processing tools. With a well-written API specification, users can automatically generate client code for your API, mock an entire server, and much more. These possibilities can give you a head start on your competitors. So remember, treat your OpenAPI Specification as code, not just as a structured document for humans.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;Here is a list of articles that can be helpful when working on API specification:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://spec.openapis.org/oas/latest.html" rel="noopener noreferrer"&gt;Specification of OpenAPI Specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://json-schema.org/specification.html" rel="noopener noreferrer"&gt;JSON Schema Specification&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Articles about design-first vs. code-first approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.stoplight.io/api-first-api-design-first-or-code-first-which-should-you-choose" rel="noopener noreferrer"&gt;Stoplight: Design first&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://apisyouwonthate.com/blog/api-design-first-vs-code-first" rel="noopener noreferrer"&gt;APIs You Won't Hate: Design First&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://swagger.io/blog/api-design/design-first-or-code-first-api-development/" rel="noopener noreferrer"&gt;Swagger: Design First&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>api</category>
      <category>webdev</category>
      <category>openapi</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
