<?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>DEV Community: Aidan Cunniffe</title>
    <description>The latest articles on DEV Community by Aidan Cunniffe (@acunniffe).</description>
    <link>https://dev.to/acunniffe</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%2F191061%2F79a542e8-6c04-428c-96cd-0fe9e14ec245.jpeg</url>
      <title>DEV Community: Aidan Cunniffe</title>
      <link>https://dev.to/acunniffe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/acunniffe"/>
    <language>en</language>
    <item>
      <title>Generate an API Changelog with Git and Optic</title>
      <dc:creator>Aidan Cunniffe</dc:creator>
      <pubDate>Wed, 12 Jul 2023 16:04:19 +0000</pubDate>
      <link>https://dev.to/acunniffe/generate-an-api-changelog-with-git-and-optic-31a</link>
      <guid>https://dev.to/acunniffe/generate-an-api-changelog-with-git-and-optic-31a</guid>
      <description>&lt;p&gt;One of the most important parts of a public API's documentation is the Changelog. During the initial discovery + integration phase, new consumers will spend most of their time reading your docs. After your consumers are integrated it becomes really important to keep them up-to-date on changes to the API. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://stripe.com/docs/changelog"&gt;Stripe&lt;/a&gt; has a great changelog that many API companies wish to emulate. It's unfortunately very difficult to keep track of, and manually document, every historical API change. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sOJsUmy8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ntyraqpgeto0jqcozb8b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sOJsUmy8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ntyraqpgeto0jqcozb8b.jpg" alt="Image description" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's where Optic (the open source API version control tool) can help. Its new &lt;code&gt;history&lt;/code&gt; command will use Git history to write a date-based changelog in markdown.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;optic history openapi.yml &amp;gt; changelog.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ke3_TEwl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/emtgmnrpeu3m1i8fcdm5.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ke3_TEwl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/emtgmnrpeu3m1i8fcdm5.jpeg" alt="Image description" width="800" height="595"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it! Now you have a Stripe-style changelog!&lt;/p&gt;

</description>
      <category>api</category>
      <category>git</category>
      <category>openapi</category>
    </item>
    <item>
      <title>Testing for Breaking Changes in Fastify APIs</title>
      <dc:creator>Aidan Cunniffe</dc:creator>
      <pubDate>Wed, 03 May 2023 15:18:21 +0000</pubDate>
      <link>https://dev.to/acunniffe/testing-for-breaking-changes-in-fastify-apis-1ja1</link>
      <guid>https://dev.to/acunniffe/testing-for-breaking-changes-in-fastify-apis-1ja1</guid>
      <description>&lt;p&gt;Recently I was approached by a team that needed help testing their Fastify API for breaking changes. Fastify was making it easy to quickly ship a lot of new functionality, but breaking changes were making it through Code Reviews. They were not finding out the changes were breaking until a consumer emailed them — not good. The developer who reached out saw my work on &lt;a href="https://github.com/opticdev/optic"&gt;the Optic project&lt;/a&gt; and asked for help. &lt;/p&gt;

&lt;p&gt;This post is about how I helped them test for breaking changes in CI. It’s written like a tutorial so you can follow along too.&lt;/p&gt;

&lt;h2&gt;
  
  
  API Lockfiles
&lt;/h2&gt;

&lt;p&gt;APIs are a contract. When you publish a new endpoint, you are making a new promise to consumers. When you change how that API works, it might break that promise. The difficulty is knowing what promises you have already made, and figuring out if your code changes break them. With all the abstractions in a backend codebase, changing one line of code can easily change a dozen API endpoints without anyone realizing it. &lt;/p&gt;

&lt;p&gt;What we need is a lockfile for our API’s behavior. That would make it easy to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Review API Diffs (the behavior changes) at the same time we do Code Review&lt;/li&gt;
&lt;li&gt;Make it possible to test for breaking API changes in CI&lt;/li&gt;
&lt;li&gt;Refactor our backend safety — lots of code can change, but the lockfile should stay the same&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fastify has great support for &lt;a href="https://github.com/fastify/fastify-swagger"&gt;generating OpenAPI&lt;/a&gt; from code. Like many other popular backend frameworks, using JSON Schema for validation and exporting OpenAPI have first-class support. We can use this generated OpenAPI specification as a lockfile for the API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating our API Lockfile (OpenAPI)
&lt;/h2&gt;

&lt;p&gt;First let’s get our current OpenAPI specification out of Fastify and onto the file system. If you have not added the &lt;a href="https://github.com/fastify/fastify-swagger"&gt;https://github.com/fastify/fastify-swagger&lt;/a&gt; plugin first go do that. Then use this simple script I called &lt;code&gt;generate-spec.ts&lt;/code&gt; to write your OpenAPI specification to the filesystem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:fs/promises&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;setupApp&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;FILE_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./openapi.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;setupApp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;FILE_PATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;swagger&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I added it to the &lt;code&gt;scripts&lt;/code&gt; section of my package JSON so it is easy to call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yarn run tsc --build --verbose&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;generate-spec&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yarn ts-node ./src/generate-spec&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the most recent OpenAPI is at &lt;code&gt;openapi.json&lt;/code&gt; and is re-generated whenever I run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;yarn&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="nx"&gt;generate&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;spec&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tracking our API lockfile with Git
&lt;/h2&gt;

&lt;p&gt;Lockfiles are one of the few generated artifacts it makes sense to track with Git. Adding generated OpenAPI specs to our git repos gives us a quick way to lookup how the API worked at various points in time using Git tags, commit SHAs, and branch names. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Suggestion:&lt;/strong&gt; if you want to ensure that the OpenAPI on each branch is accurate, consider adding the following CI task:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn run generate-spec
git diff &lt;span class="nt"&gt;--cached&lt;/span&gt; &lt;span class="nt"&gt;--exit-code&lt;/span&gt; &lt;span class="nt"&gt;--quiet&lt;/span&gt; &lt;span class="c"&gt;# will exit 1 if the checked-in spec is stale&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Testing for breaking changes
&lt;/h2&gt;

&lt;p&gt;Now that we have a way to lookup our API’s behavior with Git, we can start testing for breaking changes between versions of our API. We’ll be using Optic (&lt;a href="https://github.com/opticdev/optic"&gt;an open source tool I created&lt;/a&gt;) to do just that. If you are looking for other options I recommend &lt;a href="https://github.com/OpenAPITools/openapi-diff"&gt;https://github.com/OpenAPITools/openapi-diff&lt;/a&gt; or &lt;a href="https://github.com/Tufin/oasdiff"&gt;https://github.com/Tufin/oasdiff&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First install the Optic CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn global add @useoptic/optic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use the diff command to test for breaking changes between your feature branch and the &lt;code&gt;main&lt;/code&gt; branch. This will flag any breaking changes during Code Review.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
optic diff openapi.json &lt;span class="nt"&gt;--base&lt;/span&gt; main &lt;span class="nt"&gt;--check&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bzelvc3x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bkchw92rdmpbmicx6obh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bzelvc3x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bkchw92rdmpbmicx6obh.jpg" alt="Image description" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This command will exit 1 if a breaking change is detected so it can be used like a test in CI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E0GVAaN2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhhvlkwux6eouvj6amdt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E0GVAaN2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhhvlkwux6eouvj6amdt.jpg" alt="Image description" width="800" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bringing it all together
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Generated OpenAPI specifications can be used as API Lockfiles. Many of the most popular API frameworks have been adding first-class support for generating OpenAPI.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fastify&lt;/code&gt; + &lt;code&gt;fastify-swagger&lt;/code&gt; make it easy to generate accurate OpenAPI specifications from your code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;optic&lt;/code&gt; makes it test for API changes between Git branches and tags&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you can ship changes to your fastify APIs with confidence that you won’t break your consumers. &lt;/p&gt;

</description>
      <category>fastify</category>
      <category>api</category>
      <category>node</category>
    </item>
    <item>
      <title>An API Changelog on Every Commit</title>
      <dc:creator>Aidan Cunniffe</dc:creator>
      <pubDate>Thu, 03 Sep 2020 15:58:25 +0000</pubDate>
      <link>https://dev.to/acunniffe/an-api-changelog-on-every-commit-34dh</link>
      <guid>https://dev.to/acunniffe/an-api-changelog-on-every-commit-34dh</guid>
      <description>&lt;p&gt;Time after time I’ve encountered teams who understand the importance of API Change Management, but do not have the mechanisms in place to understand how their APIs change over time.&lt;/p&gt;

&lt;p&gt;To me, this has always felt like it should in the bucket of ‘solved problems’. We have amazing change management tools for our code and our infrastructure, but not the APIs that are run by that code, on that infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Now Available: The Optic GitBot
&lt;/h2&gt;

&lt;p&gt;Imagine a GitBot that made it easy for teams to understand how/when their APIs change. Enter the Optic GitBot, which automatically adds an API Changelog to Pull Requests within your project. With the bot installed, developers understand how each PR affects their API contract and can use these insights during code review.&lt;/p&gt;

&lt;p&gt;When you open a PR, Optic diffs the specifications in your PR branch against the base branch to produce a semantic changelog, then comments on the PR. It's that easy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X-2H-gC0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fncupz46q5hlcqgf9gym.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X-2H-gC0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fncupz46q5hlcqgf9gym.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Optic Bot is free and available to any team using Optic to maintain their API specifications. It takes 2 minutes to setup — &lt;a href="https://github.com/apps/optic-gitbot"&gt;try it now&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Solving the Hard Problems: How the Bot works
&lt;/h2&gt;

&lt;p&gt;Automatically building an API Changelog is a hard problem because it relies on 2 hard problems under-the-hood: making sure your team’s API specifications stay up-to-date and designing a meaningful changelog.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keeping the specification up-to-date.&lt;/strong&gt; Most teams, even those that practice spec/design-first, do not have up-to-date API specifications. Diffing stale specs will yield poor changelogs making it difficult to create anything useful for change management.&lt;/p&gt;

&lt;p&gt;Teams already using Optic rarely have this as a problem. Most adopted Optic because it detects API changes for their developers and makes documenting the changes as easy as making Git commits. Developers just have to approve changes "Yes, I meant to do that", instead of writing OpenAPI by hand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Making a Meaningful Changelog.&lt;/strong&gt; Useful changelogs make it easy to understand what’s changed at a glance, and reason the implications of those changes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Here's an example of a clear, and semantic diff:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZtBof57j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gvx2083r2nr0nca1j5km.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZtBof57j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gvx2083r2nr0nca1j5km.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  And here's the same example line diff:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JcR2xY4S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bagbd3evwfa3sezx3boa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JcR2xY4S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bagbd3evwfa3sezx3boa.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A line-diff is much harder to reason about, and more importantly, it's difficult to understand the scope of the changes. Because schemas are re-used, 1 line may affect multiple operations. You (the programmer) have to bring a lot of context to a raw diff like this. Where is this shared schema used? One operation? Many? In Responses or in Requests? A required field being made optional in a Request is not breaking, but in a Response the same change is considered breaking.&lt;/p&gt;




&lt;h2&gt;
  
  
  Get Started with Optic + GitBot
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Not using Optic yet? Optic is an open source project that makes writing/maintaining your API specifications as easy as making Git commits. Learn more here&lt;/em&gt; &lt;a href="https://useoptic.com/"&gt;https://useoptic.com/&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;[For New Users] Add Optic to your API&lt;/li&gt;
&lt;li&gt;Check-in your &lt;code&gt;.optic&lt;/code&gt; folder to source control&lt;/li&gt;
&lt;li&gt;Install the &lt;a href="https://github.com/apps/optic-gitbot"&gt;Optic GitBot from the GitHub Marketplace&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Open A PR&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What’s Next for the Bot
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When do breaking changes get introduced?&lt;/strong&gt; When the API changes&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When do bad design choices get introduced?&lt;/strong&gt; When the API changes&lt;/p&gt;

&lt;p&gt;We believe the best place to do API Governance is at the point of change.&lt;/p&gt;

&lt;p&gt;The Optic GitBot gives teams a process to ensures every API change gets reviewed, documented and approved. Right now, the bot simply provides visibility into changes, but soon, as more teams begin to adopt the GitBot it start nudging teams towards better designs with style guides, and prevent breaking changes from getting deployed.&lt;/p&gt;

&lt;p&gt;Have other ideas? Want to pitch in? The Optic maintainers host office hours you can schedule &lt;a href="https://useoptic.com/community"&gt;https://useoptic.com/community&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>api</category>
      <category>openapi</category>
      <category>changelog</category>
    </item>
    <item>
      <title>From Examples to an API description in 2 Minutes</title>
      <dc:creator>Aidan Cunniffe</dc:creator>
      <pubDate>Mon, 18 Nov 2019 14:23:00 +0000</pubDate>
      <link>https://dev.to/acunniffe/from-examples-to-an-api-description-in-2-minutes-21o8</link>
      <guid>https://dev.to/acunniffe/from-examples-to-an-api-description-in-2-minutes-21o8</guid>
      <description>&lt;p&gt;For new APIs, a design-first workflow is the way to go. Spending time up-front to design a good API contract and get feedback from consumers usually leads to a higher quality API being built.&lt;/p&gt;

&lt;p&gt;Many teams are interested in building new APIs design-first but it can be a daunting task get started even with popular API description formats and ecosystems like OpenAPI's.&lt;/p&gt;

&lt;p&gt;But a design-first workflow doesn’t necessarily mean you need to start by learning an API description format. In fact, you can get a lot of the benefits of a design-first workflow without using traditional API descriptions. In this post we're going to explore why designing APIs by example can be a simpler way to get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Design-by-Example
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Example requests come from the perspective of the API consumer. This builds empathy with the consumer and forces you to think more about how the API will be used. This makes the process more accessible to designers and product managers and leads to a better API design.&lt;/li&gt;
&lt;li&gt;Using example requests lowers the barrier to entry. Examples are concrete and only depend on a basic knowledge of HTTP and JSON, not the additional levels of abstraction that API description formats require.&lt;/li&gt;
&lt;li&gt;Example requests should align well with scenarios / user stories from your project management process. Often the scenarios get lost in the process of creating the spec, but this way each scenario is documented independently with examples and their relationship is preserved.&lt;/li&gt;
&lt;li&gt;A library of example requests can be turned into a spec, but a spec can’t usually generate meaningful example requests. The examples can then be used for mock data and are guaranteed to adhere to the spec.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Going from Example Requests → API Spec
&lt;/h2&gt;

&lt;p&gt;Designing-by-examples is much easier than writing a spec by hand, but what do you do from there? One option is to use Optic to build your spec from the examples — Optic knows how to build a spec from real API requests out of the box, and your examples work just as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://design.useoptic.com/spec-by-example"&gt;Add an example request/responses on Optic&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KTK0bHcW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://uploads-ssl.webflow.com/5d8b71aef4a9a52ea2cd80e9/5dd2a59eb88d00d722532398_Screen%2520Shot%25202019-11-18%2520at%25209.04.38%2520AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KTK0bHcW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://uploads-ssl.webflow.com/5d8b71aef4a9a52ea2cd80e9/5dd2a59eb88d00d722532398_Screen%2520Shot%25202019-11-18%2520at%25209.04.38%2520AM.png" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Click 'Document new API Request'
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2TlQ6Yf1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://uploads-ssl.webflow.com/5d8b71aef4a9a52ea2cd80e9/5dcf00f8ddf1beed5794b12d_Screen%2520Shot%25202019-11-15%2520at%25202.05.07%2520PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2TlQ6Yf1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://uploads-ssl.webflow.com/5d8b71aef4a9a52ea2cd80e9/5dcf00f8ddf1beed5794b12d_Screen%2520Shot%25202019-11-15%2520at%25202.05.07%2520PM.png" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Add the path to your spec
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bJwrCAp2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://uploads-ssl.webflow.com/5d8b71aef4a9a52ea2cd80e9/5dd2a5abc5a7ed23ba63fff2_Screen%2520Shot%25202019-11-18%2520at%25209.06.12%2520AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bJwrCAp2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://uploads-ssl.webflow.com/5d8b71aef4a9a52ea2cd80e9/5dd2a5abc5a7ed23ba63fff2_Screen%2520Shot%25202019-11-18%2520at%25209.06.12%2520AM.png" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Optic to document the request and response bodies
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LY3Q8Lwa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://uploads-ssl.webflow.com/5d8b71aef4a9a52ea2cd80e9/5dd2a5b6a7c3d0b84af79cfb_Screen%2520Shot%25202019-11-18%2520at%25209.06.42%2520AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LY3Q8Lwa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://uploads-ssl.webflow.com/5d8b71aef4a9a52ea2cd80e9/5dd2a5b6a7c3d0b84af79cfb_Screen%2520Shot%25202019-11-18%2520at%25209.06.42%2520AM.png" alt="alt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it! All you have to do is provide Optic with examples of how you want your API to behave and it will build your spec for you. All of your API consumers can then use Optic to make their local development process more streamlined -- any bad requests can be caught immediately. Later on you can add new examples when requirements change, and decide whether to incorporate them into the API design.&lt;/p&gt;

&lt;p&gt;We’ve seen many organizations building their own custom OpenAPI spec authoring tools to make it easier for both developers and non-developers to design their APIs according to their organizational guidelines. We hope our example-driven flow is even simpler.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Using examples to drive your API design process builds more user empathy and makes getting started more accessible to all stakeholders. If you want to try designing your API with examples consider giving Optic's &lt;a href="https://design.useoptic.com/spec-by-example"&gt;open source tooling a try.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;‍&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Problems with API Specifications (and how to build a better one)</title>
      <dc:creator>Aidan Cunniffe</dc:creator>
      <pubDate>Mon, 08 Jul 2019 16:23:14 +0000</pubDate>
      <link>https://dev.to/acunniffe/problems-with-api-specifications-and-how-to-build-a-better-one-8g8</link>
      <guid>https://dev.to/acunniffe/problems-with-api-specifications-and-how-to-build-a-better-one-8g8</guid>
      <description>&lt;h1&gt;
  
  
  Problems with API Specifications
&lt;/h1&gt;

&lt;h3&gt;
  
  
  and how Seamless built a better one...
&lt;/h3&gt;

&lt;p&gt;When we set out to build better tooling for APIs, one of the first questions we had to ask ourselves was whether we should create our own API specification format or choose to interoperate with an existing standard. &lt;/p&gt;

&lt;p&gt;OpenAPI/Swagger has a lot of momentum and choosing it as the backing representation for Seamless seemed to be the de facto "right move." There was also comic wisdom pushing us towards an existing standard like OpenAPI, RAML, API Builder, or API Blueprint.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a specification?
&lt;/h2&gt;

&lt;p&gt;Before choosing one course over another, we spent time thinking about the problem from first principles.&lt;/p&gt;

&lt;p&gt;Specifications or 'specs' describe the behavior of a piece of software specifically and with precision. The most useful specs for programmers are the ones that can be read by both a machine and a human. &lt;/p&gt;

&lt;p&gt;API specifications describe the interface of a program that can be accessed over the wire. Contemporary examples include an OpenAPI file, a protobuf definition, or graphQL schemas. They should ideally be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple for humans to work with and provide a great developer experience.&lt;/li&gt;
&lt;li&gt;Faithfully encode the interface of the API they describe.&lt;/li&gt;
&lt;li&gt;Representative of the domain with rich abstractions that are useful for the task at hand (design, code generation, doc gen).&lt;/li&gt;
&lt;li&gt;Stable. Breaking changes in complex specification are expensive for users and toolmakers to work with.&lt;/li&gt;
&lt;li&gt;Easy for tooling built on the spec to query the data they need. The interface should be stable for many years and the domain logic should not have to be replicated in tooling itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Retiring an old idea
&lt;/h2&gt;

&lt;p&gt;One of the principle assumptions baked into every competing API specification today is that the specs must be persisted in a human readable, machine readable, and human writable format. In practice, this ends up taking the form of one large YAML or JSON file.&lt;/p&gt;

&lt;p&gt;Finding a healthy intersection of these three competing concerns is difficult to achieve and riddled with tradeoffs. Here are some important examples: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Human&lt;/strong&gt; &lt;strong&gt;Readability tradeoff:&lt;/strong&gt; APIs are naturally represented as graphs. Don't believe us? Control-f and count how many times "$ref" occurs in your spec. It is difficult for humans to read a graph in linear text form, so API spec standards use trees to better communicate structure and relationships.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Impact on machine readability:&lt;/strong&gt; This puts a huge burden on each toolmaker to resolve the $refs and rebuild a graph before anything interesting can be done with your spec.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human&lt;/strong&gt; &lt;strong&gt;Writability tradeoff:&lt;/strong&gt; There are shorthands throughout spec standards today that try to make them easier to author. Examples include keywords that define authentication patterns and the use of $refs to aid in DRY (don't repeat yourself).

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Impact on machine readability:&lt;/strong&gt; When the specification is not explicit and contains shorthands like 'oauth' for auth or other semantics that are defined by the spec standards themselves, tools need to stay and current and re-implement the domain logic on their own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Impact on human readability:&lt;/strong&gt; API specs today are hard to read because of the very features that make them more writable. Seeing that a response is $ref: OrderType means I have to find OrderType, the three other types referenced there, and then build the flattened schema in my head.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Machine Readability tradeoff:&lt;/strong&gt; To make an API specification readable by machines, they must use a strict syntax (JSON or YAML) and conform to a tightly specified schema.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Impact on human readability:&lt;/strong&gt; JSON is not easy to read, especially when it is 10k + lines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Impact on human writability:&lt;/strong&gt; Nobody is born writing YAML or with perfect intuition about an API spec standard. Even experts spend a lot of time fighting the tooling.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This shape of this problem means that you can not solve it with ordinary thinking.  The more you optimize for writability, the more difficult you are going to make machine and human readability. The better it is made for machines and tooling, the worse off it is for humans to write.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  CQRS to the rescue
&lt;/h2&gt;

&lt;p&gt;Through this lens, the root problem with current spec standard becomes obvious. there is only one model that is used for both reading and writing, and it also has to support the needs of both humans and machines. We can all agree that is a lot to realistically expect from a single data model. &lt;/p&gt;

&lt;p&gt;We need models optimized for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Human Readability&lt;/strong&gt;: so programmers can easily read and understand the API being specced.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human&lt;/strong&gt; &lt;strong&gt;Writability:&lt;/strong&gt; so programmers can quickly write and modify the spec with productive abstractions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Machine Readability:&lt;/strong&gt; so tools can query the information in the spec relevant to them, ideally with something like graphQL.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But how can we get all 3 of those at once? &lt;/p&gt;

&lt;p&gt;Enter CQRS (command-query-responsibility-segregation). &lt;a href="https://docs.microsoft.com/en-us/azure/architecture/patterns/cqrs"&gt;Microsoft's docs explain that CQRS&lt;/a&gt; "separates reads and writes into separate models, using commands to update data, and queries to read data." &lt;/p&gt;

&lt;p&gt;Once we sketched out an API spec built around the principles of CQRS and Event Sourcing, things quickly fell into place. Separating concerns allowed us to optimize each use case without introducing tradeoffs. &lt;/p&gt;

&lt;p&gt;New designs and rethinking old norms change the shape of a problem space in a way that allows real progress. &lt;/p&gt;

&lt;h2&gt;
  
  
  Making it concrete
&lt;/h2&gt;

&lt;p&gt;At the center of our implementation is the open source &lt;a href="https://github.com/seamlessapis/seamless"&gt;Seamless domain engine&lt;/a&gt;. It can run on the JVM or in Node making it portable just about everywhere. At a high level, the domain engine interprets commands and handles queries. You can think of this as sort of a living specification. Instead of being a flat file, it is an actual program that answers your queries and modifies the internal API specification in response to your commands. This internal API specification is an event stream of every change you have made to your API since you started using Seamless. These events are played back every time you start the domain engine to build the current specification for your API. Each of these events are immutable facts about the API like RequestAdded, RequestBodyContentTypeSet, etc. We do not have to argue over syntax, semantics, or structure or even concern ourselves with humans reading or writing these directly. Events are pure descriptions of the API domain. &lt;/p&gt;

&lt;p&gt;Commands for the API spec domain might be things like AddQueryParameter, CreatePath, ChangeMethod, UseSchema, AddResponse, etc. It would not be very human-friendly to make a programmer write all the commands in sequence, so we have also shipped an open source API Design tool similar to Stoplight or RedHat's Apicurio. The Seamless API designer sends commands to the domain engine in response to actions taken in the UI. Visual OpenAPI designers are exploding right now. It seems inevitable that most teams will adopt one, especially as the OpenAPI format becomes more complex.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://design.seamlessapis.com"&gt;Try Designer&lt;/a&gt;
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Query what you need
&lt;/h2&gt;

&lt;p&gt;In CQRS, queries return projections (custom read models that are highly optimized for a specific use case). Some example projections might be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A list of endpoints 
— That is all you get. There is nothing you do not need.&lt;/li&gt;
&lt;li&gt;A list of schemas / types

&lt;ul&gt;
&lt;li&gt;Represented as a list of rules (great for building a test suite).&lt;/li&gt;
&lt;li&gt;with all their references flattened.&lt;/li&gt;
&lt;li&gt;as JSON schema.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Your API represented in OpenAPI 
— A traditional spec format is just another projection of the core data model. Even some of Seamless's more advanced features, such as support for Generics, can be projected onto OpenAPI.&lt;/li&gt;
&lt;li&gt;the changes made since the last version of the API.&lt;/li&gt;
&lt;li&gt;a projection optimized for generating

&lt;ul&gt;
&lt;li&gt;clients.&lt;/li&gt;
&lt;li&gt;API implementations.&lt;/li&gt;
&lt;li&gt;test suites.&lt;/li&gt;
&lt;li&gt;make your own.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because these queries are based on the event stream used for persistence, they are guaranteed to be stable for two reasons: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As a tool-builder, you can in-source the queries and projections you need to your own codebase. Imagine if OpenAPI was structured in a way that mapped more cleanly onto the domain of the tools you are building for it, forever, guaranteed.&lt;/li&gt;
&lt;li&gt;We will not accept breaking changes to projections in the main project. If you need to change the projection in a breaking way, you will be asked to name the query something else.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Benefits
&lt;/h2&gt;

&lt;p&gt;We just unpacked a lot about the architecture, now let us discuss the practical value of representing our APIs in this way. &lt;/p&gt;

&lt;h3&gt;
  
  
  Developer Experience
&lt;/h3&gt;

&lt;p&gt;Seamless both enables and requires better API design tools because nobody is running the commands manually. The market is already moving towards structured API editors, and the battle is on to improve developer experience. Once you strip away the complexity of parsing and mutating a traditional API spec, your team can focus on building a great UX (see our editor and its source as an example).&lt;/p&gt;

&lt;p&gt;Seamless also makes it possible to imagine an explosion of specialized tooling built around the API design experience. Because of the way projections and commands work, a bunch of really awesome Schema Editors could be built that only concern themselves with relevant events/commands. Tooling for generating tests could be built around their own set of specialized events/commands. With this architecture, it is fine if tools only concern themselves queries and commands relevant to their domain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Richer Abstractions
&lt;/h3&gt;

&lt;p&gt;With concerns separated properly, it is easier to implement richer abstractions to represent APIs. Many API architects want to define reusable standards for things like pagination, but this is not easily supported by JSON Schema. In Seamless, it is easy for us to support generics. Now our schemas can take other schemas as type parameters like &lt;code&gt;InfiniteScrollPagination[UserType]&lt;/code&gt; or &lt;code&gt;PageBasedPagination[UserType]&lt;/code&gt;. Generics make API standards sharable between a team's APIs.&lt;/p&gt;

&lt;p&gt;A major unsolved challenge in OpenAPI-land is diffing a spec. Proper diffs would help prevent breaking changes, generate semantic change-logs, and provide safety for teams that use code-first workflows. One of the main challenges here, besides the complex data structure, is that changes to a flat JSON/YAML file lose their intent. How can you know a query parameter was renamed 'foo' → 'bar'? A normal diff of the JSON would show 'foo' being deleted and 'bar' being added. &lt;/p&gt;

&lt;p&gt;In Seamless, every change is an event that captures intent, so you can easily build a semantic diff as a projection. In fact, there is an open feature request that displays changes to the API spec whenever you pull the repo. &lt;/p&gt;

&lt;p&gt;Finally, in the real world, teams are using a combination of REST, graphQL, Websockets, and RPCs, often times within the same APIs. A traditional spec combining all these paradigms would collapse under the weight of its own complexity, but it is possible for Seamless to support multiple paradigms and common components between them. We suspect this kind of interoperability will become more important in the next few years, especially in enterprise settings. &lt;/p&gt;

&lt;h3&gt;
  
  
  Governance
&lt;/h3&gt;

&lt;p&gt;The way Seamless' domain is set up means that contributors just have to answer one question "What can we say about a REST API?"&lt;/p&gt;

&lt;p&gt;If it can have requests, then we need an event for RequestAdded.&lt;/p&gt;

&lt;p&gt;If each request can have query parameters, then we need an event for QueryParameterAdded. &lt;/p&gt;

&lt;p&gt;If each query parameter can have a shape, then we need ParameterShapeSet.&lt;/p&gt;

&lt;p&gt;Do we need to support generics? That's just 2 new events and 1 query. &lt;/p&gt;

&lt;p&gt;Keeping the domain simple, representative, and pure is the most important task for us, and that is much easier for a group of contributors to manage compared to a traditional spec standard.&lt;/p&gt;

&lt;p&gt;Once the domain modeling is taken care of, the needs of toolmakers will direct the development of the Commands and Queries that get built. &lt;/p&gt;

&lt;h2&gt;
  
  
  Tradeoffs
&lt;/h2&gt;

&lt;p&gt;There are some clear tradeoffs to this design as well. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Seamless relies on GUI API Designers to be built around it. We have shipped an awesome open-source one to get things started, but we need more competitive solutions to grow and evolve in parallel.&lt;/li&gt;
&lt;li&gt;Thinking in CQRS is hard. Contributors who are unfamiliar with the concepts will have to invest their time and mental energy in learning. However, thinking in OpenAPI, RAML, or API Blueprint is also difficult. We think it is easier to ask a small group of contributors to learn CQRS so that the millions of developers who need to design their APIs can benefit from better tooling.&lt;/li&gt;
&lt;li&gt;While CQRS naturally supports collaborative editing, the infrastructure needed to distribute events across clients is complex and relies on eventual consistency. Microsoft does a good job of explaining the tradeoffs of using &lt;a href="https://docs.microsoft.com/en-us/azure/architecture/patterns/cqrs"&gt;CQRS to represent your data here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  OpenAPI Support
&lt;/h2&gt;

&lt;p&gt;We have used OpenAPI for many years and believe it will remain a going-concern for a long time. To make it easier to get started with Seamless, we built an OpenAPI importer with support for version 2 and 3. You can &lt;a href="https://design.seamlessapis.com/upload-oas"&gt;upload your spec here to try out Seamless&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;There is also a projection in progress that outputs valid OpenAPI 3 that should play well with your existing tools. &lt;/p&gt;

&lt;p&gt;Cool aside: The architecture for the importer is inspired by GraphQL and allows us to query the information we need from the spec directly. The resolvers manage the differences between versions 2 and 3. &lt;a href="https://github.com/seamlessapis/seamless/blob/master/oas/src/main/scala/com/seamless/oas/Schemas.scala"&gt;Check out the source here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Closing
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Traditional specifications form communities around the same schema. We would like to imagine with our specification, communities will form around similar jobs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nobody wakes up thinking, "today we are going to build another way to spec APIs." We certainly did not.&lt;/p&gt;

&lt;p&gt;We believe every API should interoperate Seamlessly. This is not going to be the case until consuming APIs is as easy as installing node modules and designing them is a fluid experience. &lt;/p&gt;

&lt;p&gt;Despite server generators, SDK generators, and spec standards existing for over a decade, connecting APIs and clients is not effortless for most teams. Do not get us wrong, there are many teams who have a good end-to-end process and reap enormous benefits. There is so a lot of cool work out there. As they say, "the future is here, it is just not evenly distributed." &lt;/p&gt;

&lt;p&gt;We think a better API spec that enables a whole new ecosystem of tooling is a critical piece of infrastructure, and we are happy to open source our work and give it to the community. &lt;/p&gt;

&lt;p&gt;We look forward to hearing your comments, ideas, and concerns and working on ways to incorporate them into the project.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/seamlessapis/seamless"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/seamlessapis/seamless/issues"&gt;Issues&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
