Skip to content

FDN-4939: Add OpenAPI 3.x import support#970

Open
jackl wants to merge 13 commits into
mainfrom
FDN-4416-add-openapi-importer
Open

FDN-4939: Add OpenAPI 3.x import support#970
jackl wants to merge 13 commits into
mainfrom
FDN-4416-add-openapi-importer

Conversation

@jackl
Copy link
Copy Markdown
Contributor

@jackl jackl commented May 20, 2026

Summary

Jira: https://flowio.atlassian.net/browse/FDN-4416

Adds OpenAPI 3.x import support to apibuilder following the same pattern as the existing Swagger 2.0 module.

  • New openapi sbt module with a full schema classification and conversion pipeline (objects, enums, arrays, unions, aliases, maps, security schemes, paths/operations/parameters/responses)
  • Auto-detects OpenAPI 3.x specs (JSON and YAML) in OriginalUtil.guessType, dispatching to OpenApiServiceValidator via OriginalType.UNDEFINED("open_api_3")
  • ConverterMain CLI for developer testing — run directly from sbt while iterating on conversions:
    sbt "openapi/runMain io.apibuilder.openapi.ConverterMain ./openapi.json --organization myorg --json"
    sbt "openapi/runMain io.apibuilder.openapi.ConverterMain https://petstore3.swagger.io/api/v3/openapi.json --organization myorg"
    

Dependencies

  • com.github.apicollective:apibuilder-validation:0.5.8 via JitPack (Scala 3 artifact published without version suffix — uses single %)
  • com.softwaremill.sttp.apispec 0.11.10 for the OpenAPI model

Test plan

  • 67 unit tests covering schema classification, type conversion, security schemes, naming utilities, and end-to-end conversion of three real-world FedEx OpenAPI 3.x specs
  • sbt "openapi/test" → all pass

Notes

  • Uses OriginalType.UNDEFINED("open_api_3") to avoid a blocking API spec change; a follow-up ticket should add a proper OriginalType.OpenApi3 value
  • PathConverter has no dedicated unit spec (covered indirectly via FedEx integration tests); a follow-up can add PathConverterSpec

Eng-Review Summary

  • Revision: a38e28f
  • Timestamp: 2026-05-20T10:46:16Z
  • Status: passed_with_notes
  • Issues:
    • Tag: TESTING
      Title: PathConverter lacks dedicated unit tests
      Location: no PathConverterSpec
      Resolution: justified
      Justification: Covered indirectly via FedEx integration tests in ConverterSpec; unit spec to follow in a subsequent PR

jackl and others added 3 commits May 20, 2026 11:30
Implement OpenAPI 3.x import functionality following the existing Swagger 2.0 pattern. The new openapi module provides:
- Schema classification and conversion pipeline
- Type mapping from OpenAPI schema types to apibuilder scalar types
- Path/operation/parameter conversion
- Security scheme handling
- Full test coverage with FedEx OpenAPI specs

Uses OriginalType.UNDEFINED("open_api_3") for import detection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jackl jackl changed the title FDN-4416: Add OpenAPI 3.x import support FDN-4939: Add OpenAPI 3.x import support May 20, 2026
jackl and others added 2 commits May 20, 2026 15:47
… coverage

- Narrow broad Exception catch in namespace inference to IllegalArgumentException
- Replace unsafe .get calls with sys.error in ConverterMain
- refName warns and returns raw string for non-standard $ref formats
- resolveReference returns Either[String,String] instead of throwing on cycles
- Warn when fields are dropped due to unresolved type (kind=None)
- Warn at each array item type string fallback
- Record issue when path has no typed response and is excluded from resources
- Warn when requestBody $ref cannot be resolved
- Wrap Converter.convert in Try in OpenApiServiceValidator for defence-in-depth
- Wrap fromYaml/fromJson errors with JSON/YAML context prefix
- Include exception class name in fromFile/fromUrl error messages
- Add PathConverterSpec, SchemaResolverSpec, ConverterMainSpec, OpenApiParserSpec
- Expand SchemaConverterSpec with SchemaConverter.convert output assertions
- Expand ConverterSpec: assert resources non-empty, specific model names, filterHeaders e2e
- Add NamingUtils edge cases and ApibuilderPrimitiveTypes membership tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jackl jackl requested a review from mbryzek May 20, 2026 16:08
jackl and others added 8 commits May 21, 2026 09:43
…rage

- classifyField now unwraps oneOf/anyOf nullable primitives: filters out the
  null member and classifies the remaining single primitive, fixing ~200
  previously unmapped fields that used the oneOf+null pattern
- Extend FormatMap with unixtime (→ long), uri/binary/byte/password/email
  (→ string), eliminating ~126 spurious ignored-format report entries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds int8/int16/int32, uint8/uint16/uint32/uint64, double-int, decimal128,
date-time-local, http-date, duration, uri-reference, uri-template, iri,
iri-reference, idn-email, hostname, idn-hostname, base64url, sf-binary,
html, commonmark, media-range, json-pointer, relative-json-pointer, regex,
and char. Includes a link to the registry as the authoritative source.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously, each non-JSON content type generated a separate warning line,
and warnings fired even when a JSON alternative existed for the same
operation. Now:
- Only warn when no application/json alternative is present (if JSON is
  available it is used and other types are silently ignored)
- Consolidate all non-JSON types into one message per response/body
- Format response keys as plain codes (200, default, 3xx) not case-class names

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a request body has no application/json content but the form content
type carries a $ref schema, use that schema as the body type. This recovers
the body type for file-upload and form-submission endpoints that define a
named request model. The non-JSON body warning is also suppressed when a
schema ref is successfully extracted.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds briefSummary to ConversionReport and writes it into the service
description alongside the original OpenAPI description. Also emits an
openapi_conversion attribute with per-category issue lists for tooling
to consume.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Both types now produce an Authorization: Bearer header (matching the
http/bearer treatment) rather than being skipped. The header description
includes OAuth2 flow details (flow type, tokenUrl, scopes) or the
OpenID Connect discovery URL so the information is not silently lost.
A degraded note is emitted into the openapi_conversion attribute for
each partially-converted scheme.

Per-operation security warnings in PathConverter are suppressed when
all referenced scheme names are convertible, and only fire for
genuinely unconvertible schemes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
oauth2 schemes now carry an 'oauth2' attribute with the full flows
object (authorization/token URLs, refresh URL, scopes per flow).
openIdConnect schemes carry an 'openid_connect' attribute with the
discovery URL. This makes the security metadata machine-readable in
the apibuilder output rather than only visible in the description text.
Degraded notes updated to reference the attribute rather than saying
the data is not representable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant