1"use strict";(self.webpackChunkbeeceptor_docs=self.webpackChunkbeeceptor_docs||[]).push([["7307"],{80254(e,n,s){s.r(n),s.d(n,{metadata:()=>i,default:()=>h,frontMatter:()=>t,contentTitle:()=>l,toc:()=>c,assets:()=>o});var i=JSON.parse('{"id":"web-basics/openapi-new-3.1.0","title":"OpenAPI 3.1.0 Compared to 3.0.3","description":"A detailed guide comparing OpenAPI 3.1.0 vs 3.0.3. Understand key differences in JSON Schema support, webhooks, nullable, examples, and $ref behavior.","source":"@site/docs/web-basics/openapi-3-1-vs-3-0.md","sourceDirName":"web-basics","slug":"/concepts/openapi-what-is-new-3.1.0","permalink":"/docs/concepts/openapi-what-is-new-3.1.0","draft":false,"unlisted":false,"tags":[{"inline":true,"label":"Learnings","permalink":"/docs/tags/learnings"}],"version":"current","sidebarPosition":24,"frontMatter":{"id":"openapi-new-3.1.0","slug":"/concepts/openapi-what-is-new-3.1.0","title":"OpenAPI 3.1.0 Compared to 3.0.3","description":"A detailed guide comparing OpenAPI 3.1.0 vs 3.0.3. Understand key differences in JSON Schema support, webhooks, nullable, examples, and $ref behavior.","sidebar_label":"OpenAPI: 3.1.0 & 3.0.3 Compared","sidebar_position":24,"tags":["Learnings"],"date":"2025-05-10T20:00:00.000Z"},"sidebar":"tutorialSidebar","previous":{"title":"OpenAPI: Step By Step Learning","permalink":"/docs/concepts/openapi-specification-tutorial"},"next":{"title":"OpenAPI: Sample Spec","permalink":"/docs/concepts/openapi-sample-spec"}}'),a=s(74848),r=s(28453);let t={id:"openapi-new-3.1.0",slug:"/concepts/openapi-what-is-new-3.1.0",title:"OpenAPI 3.1.0 Compared to 3.0.3",description:"A detailed guide comparing OpenAPI 3.1.0 vs 3.0.3. Understand key differences in JSON Schema support, webhooks, nullable, examples, and $ref behavior.",sidebar_label:"OpenAPI: 3.1.0 & 3.0.3 Compared",sidebar_position:24,tags:["Learnings"],date:new Date("2025-05-10T20:00:00.000Z")},l,o={},c=[{value:"Compare OpenAPI 3.1.0 vs 3.0.3",id:"compare-openapi-310-vs-303",level:2},{value:"1. JSON Schema Compatibility",id:"1-json-schema-compatibility",level:2},{value:"2. $schema Declaration at Root",id:"2-schema-declaration-at-root",level:2},{value:"3. Webhooks Support",id:"3-webhooks-support",level:2},{value:"4. Server Variable default Is Optional",id:"4-server-variable-default-is-optional",level:2},{value:"5. <code>nullable</code> Deprecated",id:"5-nullable-deprecated",level:2},{value:"6. Examples Are Now First-Class JSON Schema Keywords",id:"6-examples-are-now-first-class-json-schema-keywords",level:2},{value:"7. Better <code>$ref</code> Behavior",id:"7-better-ref-behavior",level:2},{value:"Final Thoughts",id:"final-thoughts",level:2}];function d(e){let n={a:"a",code:"code",h2:"h2",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.p,{children:"If you work with API specifications, you've likely come across the OpenAPI Specification (OAS). OpenAPI 3.1.0 brought some important changes that directly impact how we define and consume API contracts. Whether you're a developer writing API specs or a QA working on automation, it's useful to understand what changed between 3.0.3 and 3.1.0 and why it matters."}),"\n",(0,a.jsx)(n.h2,{id:"compare-openapi-310-vs-303",children:"Compare OpenAPI 3.1.0 vs 3.0.3"}),"\n",(0,a.jsx)(n.p,{children:"Here's a quick summary:"}),"\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Feature"}),(0,a.jsx)(n.th,{children:(0,a.jsx)(n.a,{href:"https://spec.openapis.org/oas/v3.0.3.html",children:"OpenAPI 3.0.3"})}),(0,a.jsx)(n.th,{children:(0,a.jsx)(n.a,{href:"https://spec.openapis.org/oas/v3.1.0.html",children:"OpenAPI 3.1.0"})})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"JSON Schema version"}),(0,a.jsx)(n.td,{children:"Partial (draft-04 like)"}),(0,a.jsx)(n.td,{children:"Full (Draft 2020-12)"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsxs)(n.td,{children:[(0,a.jsx)(n.code,{children:"$schema"})," support"]}),(0,a.jsx)(n.td,{children:"Not supported"}),(0,a.jsx)(n.td,{children:"Supported at top-level"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Webhooks"}),(0,a.jsx)(n.td,{children:"Not supported"}),(0,a.jsxs)(n.td,{children:["Supported via ",(0,a.jsx)(n.code,{children:"webhooks"})," object"]})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"nullable"})}),(0,a.jsx)(n.td,{children:"Supported (custom keyword)"}
1),(0,a.jsx)(n.td,{children:"Deprecated in favor of type union"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsxs)(n.td,{children:[(0,a.jsx)(n.code,{children:"example"})," keyword"]}),(0,a.jsx)(n.td,{children:"Limited"}),(0,a.jsx)(n.td,{children:"Fully supported in schemas"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsxs)(n.td,{children:["Server variable ",(0,a.jsx)(n.code,{children:"default"})]}),(0,a.jsx)(n.td,{children:"Required"}),(0,a.jsx)(n.td,{children:"Optional"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsxs)(n.td,{children:[(0,a.jsx)(n.code,{children:"$ref"})," behavior"]}),(0,a.jsx)(n.td,{children:"Restricted (no siblings)"}),(0,a.jsx)(n.td,{children:"Standard JSON Schema behavior"})]})]})]}),"\n",(0,a.jsx)(n.p,{children:"Let's walk through the key differences with examples and rationale."}),"\n",(0,a.jsx)(n.h2,{id:"1-json-schema-compatibility",children:"1. JSON Schema Compatibility"}),"\n",(0,a.jsx)(n.p,{children:"OpenAPI 3.0.3 supported a partial and modified form of JSON Schema, which led to confusion and limitations in tooling. For example, custom keywords like nullable were not part of the JSON Schema specification, and features like conditional logic or reusable fragments were either unavailable or required workarounds."}),"\n",(0,a.jsx)(n.p,{children:"OpenAPI 3.1.0 fixes this by fully aligning with JSON Schema Draft 2020-12. This change simplifies authoring and increases interoperability."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"3.0.3 Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"schema:\n type: string\n nullable: true\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"3.1.0 Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'schema:\n type: ["string", "null"]\n'})}),"\n",(0,a.jsx)(n.p,{children:"Impact:\nAdvanced JSON Schema features are now available, and schemas are easier to validate using standard tools."}),"\n",(0,a.jsx)(n.h2,{id:"2-schema-declaration-at-root",children:"2. $schema Declaration at Root"}),"\n",(0,a.jsx)(n.p,{children:"OpenAPI 3.0.3 documents did not specify which JSON Schema version they were compatible with, making schema validation inconsistent across tools."}),"\n",(0,a.jsx)(n.p,{children:"OpenAPI 3.1.0 introduces the $schema keyword at the root, which explicitly states the dialect being used. This is especially useful for tooling and validators."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"3.1.0 Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'$schema: "https://spec.openapis.org/oas/3.1.0"\nopenapi: 3.1.0\ninfo:\n title: Sample API\n version: 1.0.0\n'})}),"\n",(0,a.jsx)(n.p,{children:"Impact:\nTools can now correctly interpret the specification, improving validation accuracy."}),"\n",(0,a.jsx)(n.h2,{id:"3-webhooks-support",children:"3. Webhooks Support"}),"\n",(0,a.jsx)(n.p,{children:"Previously, OpenAPI had no native way to describe how an API receives external calls, such as webhooks triggered by external systems."}),"\n",(0,a.jsx)(n.p,{children:"OpenAPI 3.1.0 introduces a new webhooks object. This makes it possible to describe asynchronous and event-driven APIs more completely."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"3.1.0 Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"webhooks:\n newPet:\n post:\n requestBody:\n required: true\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/Pet'\n responses:\n '200':\n description: Webhook received\n"})}),"\n",(0,a.jsx)(n.p,{children:"Impact:\nYou can now document webhook endpoints directly in the spec."}),"\n",(0,a.jsx)(n.h2,{id:"4-server-variable-default-is-optional",children:"4. Server Variable default Is Optional"}),"\n",(0,a.jsx)(n.p,{children:"In 3.0.3, server variables required a default value, even if it didn\u2019t make sense in the context. This added unnecessary constraints when defining environments."}),"\n",(0,a.jsx)(n.p,{children:"3.1.0 changes this. default is now optional, matching JSON Schema behavior and making specs more flexible."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"3.0.3 Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"variables:\n env:\n enum:\n - dev\n - prod\n default: dev\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"3.1.0 Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"variables:\n env:\n enum:\n - dev\n - prod\n"})}),"\n",(0,a.jsx)(n.p,{children:"Impact:\nLess boilerplate when a default is not meaningful."}),"\n",(0,a.jsxs)(n.h2,{id:"5-nullable-deprecated",children:["5. ",(0,a.jsx)(n.code,{children:"nullable"})," Deprecated"]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"nullable"})," keyword was a custom OpenAPI extension in 3.0.3, which caused confusion when working with JSON Schema tools."]}),"\n",(0,a.jsx)(n.p,{children:"In 3.1.0, this is replaced with the standard JSON Schema a
1pproach using union types."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Before (3.0.3):"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"schema:\n type: string\n nullable: true\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"After (3.1.0):"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'schema:\n type: ["string", "null"]\n'})}),"\n",(0,a.jsx)(n.p,{children:"Impact:\nAligns with JSON Schema and improves compatibility with schema validators."}),"\n",(0,a.jsx)(n.h2,{id:"6-examples-are-now-first-class-json-schema-keywords",children:"6. Examples Are Now First-Class JSON Schema Keywords"}),"\n",(0,a.jsx)(n.p,{children:"In 3.0.3, examples could only be used in certain parts of the spec. They were not allowed directly inside JSON Schema definitions."}),"\n",(0,a.jsx)(n.p,{children:"OpenAPI 3.1.0 fixes this. Now you can embed example inside any JSON Schema object."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"3.1.0 Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'schema:\n type: object\n properties:\n name:\n type: string\n example: "Max"\n'})}),"\n",(0,a.jsx)(n.p,{children:"Impact:\nMakes specs more expressive and readable."}),"\n",(0,a.jsxs)(n.h2,{id:"7-better-ref-behavior",children:["7. Better ",(0,a.jsx)(n.code,{children:"$ref"})," Behavior"]}),"\n",(0,a.jsx)(n.p,{children:"In OpenAPI 3.0.3, $ref could not be used with sibling keywords like description or example. This often forced workarounds using allOf."}),"\n",(0,a.jsx)(n.p,{children:"OpenAPI 3.1.0 aligns $ref behavior with JSON Schema, removing those restrictions."}),"\n",(0,a.jsx)(n.p,{children:"Impact:\nYou can now use $ref more naturally and expressively in your specs."}),"\n",(0,a.jsx)(n.h2,{id:"final-thoughts",children:"Final Thoughts"}),"\n",(0,a.jsx)(n.p,{children:"If you're starting a new project, prefer 3.1.0. The full JSON Schema support alone makes it worth the upgrade. However, if you're working with tools that don\u2019t yet support 3.1.0, you may want to stick with 3.0.3 for now."})]})}function h(e={}){let{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453(e,n,s){s.d(n,{R:()=>t,x:()=>l});var i=s(96540);let a={},r=i.createContext(a);function t(e){let n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.