-
Notifications
You must be signed in to change notification settings - Fork 1
Upgrading to v2
Who needs to read this: anyone generating from an OpenAPI 3.0 document that uses
nullable: trueon a property that has notypeof its own β typically alongsideallOforoneOf.If your specifications do not contain that shape, v2 is a drop-in upgrade and you can stop here. The generator will tell you: build with
"validateSpecificationStrategy": "Strict"and ruleATC_API_VER001reports every occurrence with a line number.
v2 moves to Microsoft.OpenApi 3.10.2, which brought the parser in line with the OpenAPI
specification on one point: nullable: true only applies when type is declared in the same
Schema Object, and it does not reach through allOf / oneOf.
Earlier parser versions honoured it anyway. Generated code therefore treated some properties as nullable that the specification never considered nullable.
billingAccount:
nullable: true # no `type` beside it
oneOf:
- $ref: '#/components/schemas/IdName'- public IdName? BillingAccount { get; init; }
+ public IdName BillingAccount { get; init; }- readonly billingAccount?: IdName | null;
+ readonly billingAccount?: IdName;
β οΈ This does not break your build β that is what makes it worth your attention. The property is still optional, so everything compiles. Under<Nullable>enable</Nullable>orstrictNullChecksthe value is simply no longer declared as possibly-null, so the compiler stops warning about unguarded access at exactly the places a null can still arrive over the wire.
Search your specifications for nullable: true and check whether each one has a type: at the
same indentation, in the same mapping block. The generator does this for you β see
ATC_API_VER001 in Analyzer Rules.
| Shape | Affected? |
|---|---|
type: string + nullable: true
|
β No β valid OpenAPI 3.0, still works |
type: [string, "null"] |
β No β the OpenAPI 3.1 form, works |
nullable: true with allOf / oneOf and no type
|
β Yes |
nullable: true with no type at all |
β Yes |
First decide, per property, whether it should be nullable at all. This shape has been a no-op for as
long as the specification has existed, so the API may genuinely never return null β in which case the
right fix is to delete the nullable: true, not translate it. Translating on autopilot widens
contracts that were already correct.
Where the property is genuinely nullable:
Staying on OpenAPI 3.0 β nest the composition inside a oneOf with a nullable branch:
billingAccount:
oneOf:
- $ref: '#/components/schemas/IdName'
- type: object
nullable: trueOn OpenAPI 3.1 or later β use the null type, which is cleaner and needs no restructuring:
billingAccount:
oneOf:
- $ref: '#/components/schemas/IdName'
- type: "null"Then regenerate and diff. Once fixed, the diff against your v1 output should be empty.
Backwards compatibility was kept everywhere the information survives parsing:
| Spelling | 3.0 | 3.1 | 3.2 |
|---|---|---|---|
type: string + nullable: true
|
β | β | β |
type: [string, "null"] |
n/a | β | β |
nullable: true + allOf: [$ref]
|
β | β | β |
oneOf: [$ref, {type: "null"}] |
n/a | β | β |
oneOf: [$ref, {type: object, nullable: true}] |
β | β | β |
nullable: true is still honoured in OpenAPI 3.1 and 3.2 documents even though the keyword was
removed from the specification there β a deliberate compatibility choice, so that moving a
specification to 3.1 does not silently change your models.
The single β is the case in this guide: in a 3.0 document the parser consumes the keyword and discards it, leaving nothing for the generator to act on.
-
Four migration rules,
ATC_API_VER001βVER004, report the constructs whose meaning depends on the declared OpenAPI version β each with a line number, a suggested rewrite and a link back here. See Working with Nullability. -
Nullable references in a
oneOfare now understood β both{type: "null"}(3.1) and{type: object, nullable: true}(3.0). Previously either extra branch degraded the property toobject/unknown. This is what makes the fix above actually produceIdName?. -
Multi-reference
oneOf/anyOfproperties emit a TypeScript union (A | B | C) instead ofunknown, matching what the Zod schema emitter already produced. -
HTTP
QUERY(OpenAPI 3.2) is supported across all three client flavours β see Working with OpenAPI.
Working with Nullability has the full story: what the OpenAPI Initiative changed and why, the specification wording this rests on, a version-by-version comparison of parser behaviour, and links to the primary sources.
π Home
- πΌ FAQ Business Value
- π Getting Started with Basic
- π οΈ Getting Started with CLI
- π Migration Guide
- β¬οΈ Upgrading to v2
- π Working with OpenAPI
- π³οΈ Working with Nullability
- π οΈ Working with CLI
- π How-To Guides
- π Working with Security
- π¦ Working with Rate Limiting
- π Working with Resilience
- ποΈ Working with Caching
- π’ Working with Versioning
- β Working with Validations
- π Working with Webhooks
- βοΈ Working with Aspire
- π£οΈ Working with Endpoint Definitions
- π Working with Multi-Part Specs
- π§ͺ Working with Code Coverage
- π Working with C# Client
- π§ͺ Working with C# Client Testing
- π¦ Working with TypeScript Client
- πͺ Showcase Demo
- π§ͺ Working with E2E Testing
- βοΈ Working with Configuration
- π Marker Files
- π API Reference
- π Analyzer Rules
- β FAQ and Troubleshooting
- πΊοΈ Roadmap
- π§ Development Notes
- π¦ GitHub Repository
- π₯ NuGet Package
- π Report Issues