Skip to content

Conversation

@thivindu
Copy link
Contributor

@thivindu thivindu commented Nov 18, 2025

Purpose

The Management Portal requires API creation via Contract Flow via URL and OpenAPI definition file upload. Therefore, the provided OpenAPI definition needs to be validated, parsed and the API metadata needs to sent to the frontend.

Fixes: wso2/api-platform/issues#159

Goals

Validate and parse the provided API definition.

Approach

This pull request introduces a new endpoint for validating OpenAPI definitions via file upload or URL, along with the necessary backend logic and OpenAPI documentation updates. The main goal is to allow users to validate OpenAPI specs and extract API metadata through a unified interface.

Key changes include:

API Endpoint and Handler

  • Added a new POST endpoint /api/v1/validate/open-api that accepts multipart form data, allowing users to upload an OpenAPI definition file or provide a URL. The handler prioritizes the file if both are provided and returns validation results and extracted metadata. [1] [2]

DTOs and Service Logic

  • Introduced ValidateOpenAPIRequest and OpenAPIValidationResponse DTOs to represent the request and response for OpenAPI validation, supporting both file and URL inputs and encapsulating validation results and extracted API details.
  • Implemented ValidateOpenAPIDefinition in the service layer to handle fetching/parsing the OpenAPI content, validating it, and extracting API metadata using libopenapi.

Utility Enhancements

  • Added utility methods for fetching OpenAPI definitions from a URL, parsing both OpenAPI 3.x and Swagger 2.0 specs, and extracting operations and backend services directly into the internal API DTO.

OpenAPI Specification Updates

  • Documented the new /validate/open-api endpoint, including request/response schemas, in the OpenAPI YAML. Defined the ValidateOpenAPIRequest and OpenAPIValidationResponse schemas to match the new API. [1] [2] [3]

These changes provide a robust and user-friendly way to validate OpenAPI definitions and extract relevant API information through the platform API.

Summary by CodeRabbit

  • New Features
    • POST /validate/open‑api endpoint to validate an OpenAPI definition via URL or file upload (file prioritized when both provided).
    • Supports OpenAPI 3.x and Swagger 2.0; returns validation status, error list, and extracted API metadata (name, version, operations, backend services).
  • Documentation
    • Validation schemas and the new endpoint are added to the API specification and integrated with the API import flow.

@thivindu thivindu requested review from DakshithaS and malinthaprasan and removed request for DakshithaS November 18, 2025 09:12
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 18, 2025

Walkthrough

Adds OpenAPI validation: DTOs for request/response, a POST /validate/open-api handler and route, service method to read/validate definitions from URL or uploaded file, utility functions to fetch/parse OpenAPI 3.x and Swagger 2.0 into internal API DTO, and OpenAPI spec updates with new schemas and endpoint.

Changes

Cohort / File(s) Summary
DTOs
platform-api/src/internal/dto/openapi.go
New DTOs: ValidateOpenAPIRequest (url string, definition *multipart.FileHeader) and OpenAPIValidationResponse (isAPIDefinitionValid, errors, optional api).
Handler & Routes
platform-api/src/internal/handler/api.go
Adds APIHandler.ValidateOpenAPI and registers POST /api/v1/validate/open-api; parses multipart form (max 10 MB), requires URL or file, delegates to service, returns validation response.
Service
platform-api/src/internal/service/api.go
Adds APIService.ValidateOpenAPIDefinition(req *dto.ValidateOpenAPIRequest) (*dto.OpenAPIValidationResponse, error) — reads bytes from URL or uploaded file, invokes parsing utilities, aggregates validation result and errors.
Utilities
platform-api/src/internal/utils/api.go
Adds helpers: FetchOpenAPIFromURL, ParseAPIDefinition, parseOpenAPI3Document, parseSwagger2Document, parseDocumentByStructure, extractOperationsFromV3Paths, extractOperationsFromV2Paths, convertSwagger2ToBackendServices to map OpenAPI/Swagger into dto.API.
API Spec
platform-api/src/resources/openapi.yaml
Adds POST /validate/open-api path and component schemas ValidateOpenAPIRequest and OpenAPIValidationResponse; updates ImportAPIProjectRequest to include required api field.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Handler as APIHandler
    participant Service as APIService
    participant Util as APIUtil
    participant Remote as HTTP/File

    Client->>Handler: POST /validate/open-api (url or file)
    activate Handler
    Handler->>Handler: parse multipart form (max 10MB)
    Handler->>Handler: ensure url or file present
    Handler->>Service: ValidateOpenAPIDefinition(request)
    deactivate Handler

    activate Service
    alt URL provided
        Service->>Util: FetchOpenAPIFromURL(url)
        activate Util
        Util->>Remote: HTTP GET
        Remote-->>Util: payload (YAML/JSON)
        Util-->>Service: []byte content
        deactivate Util
    else File provided
        Service->>Service: read uploaded file bytes
    end

    Service->>Util: ParseAPIDefinition(content)
    activate Util
    Util->>Util: detect spec version / structure
    alt OpenAPI 3.x
        Util->>Util: parseOpenAPI3Document -> extractOperationsFromV3Paths
    else Swagger 2.0
        Util->>Util: parseSwagger2Document -> extractOperationsFromV2Paths -> convertSwagger2ToBackendServices
    else Fallback
        Util->>Util: parseDocumentByStructure
    end
    Util-->>Service: *dto.API (or error list)
    deactivate Util

    Service-->>Handler: *dto.OpenAPIValidationResponse
    deactivate Service

    Handler-->>Client: 200 OK {isAPIDefinitionValid, errors?, api?}
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay extra attention to:
    • Mapping logic in parseOpenAPI3Document / parseSwagger2Document and operation extraction functions.
    • Multipart form handling, file reading, size limit and resource cleanup in handler.
    • Error aggregation vs returned errors behavior in ValidateOpenAPIDefinition.

Possibly related PRs

Suggested reviewers

  • malinthaprasan

Poem

🐰 I nibble specs both near and far,
URL or file — I know what you are.
Swagger or v3, I parse and sing,
Operations hop out, a tidy spring.
Validator rabbit gives the API its star ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description check ❓ Inconclusive The PR description covers Purpose, Goals, and Approach sections from the template. However, it lacks User stories, Documentation, Automation tests, Security checks, Samples, Related PRs, and Test environment sections required by the template. Complete missing sections: add User stories, Documentation status, Automation test details (unit/integration), Security verification checklist, Samples overview, Related PRs, and Test environment specifications.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title directly corresponds to the main objective of the PR: adding validation for OpenAPI definitions. It accurately summarizes the primary change without being vague or misleading.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 40cfb53 and 7694a6e.

📒 Files selected for processing (2)
  • platform-api/src/internal/service/api.go (2 hunks)
  • platform-api/src/internal/utils/api.go (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-12T08:52:52.909Z
Learnt from: thivindu
Repo: wso2/api-platform PR: 142
File: platform-api/src/resources/openapi.yaml:905-969
Timestamp: 2025-11-12T08:52:52.909Z
Learning: In the wso2/api-platform repository, the team follows an API-first development approach where OpenAPI specs may document planned features before backend implementation is complete, allowing frontend development to proceed against the intended API contract without requiring changes later.

Applied to files:

  • platform-api/src/internal/service/api.go
  • platform-api/src/internal/utils/api.go
🧬 Code graph analysis (2)
platform-api/src/internal/service/api.go (2)
platform-api/src/internal/dto/openapi.go (2)
  • ValidateOpenAPIRequest (27-30)
  • OpenAPIValidationResponse (33-37)
platform-api/src/internal/dto/api.go (1)
  • API (25-51)
platform-api/src/internal/utils/api.go (2)
platform-api/src/internal/dto/api.go (5)
  • API (25-51)
  • Operation (134-138)
  • OperationRequest (141-148)
  • AuthenticationConfig (157-160)
  • Policy (163-166)
platform-api/src/internal/dto/backend_service.go (2)
  • BackendService (23-36)
  • BackendEndpoint (39-45)
🔇 Additional comments (8)
platform-api/src/internal/service/api.go (1)

1318-1377: LGTM!

The validation flow correctly handles both URL and file inputs with proper fallback behavior. The method:

  • Fetches from URL if provided, allowing file fallback on URL fetch failure
  • Validates the OpenAPI definition syntax
  • Parses metadata into API DTO
  • Only sets IsAPIDefinitionValid: true after both validation and parsing succeed

The implementation properly addresses the past review feedback about URL/file prioritization.

platform-api/src/internal/utils/api.go (7)

1127-1148: LGTM!

The HTTP client properly implements a 30-second timeout and handles errors appropriately. Past review feedback has been addressed.


1150-1174: LGTM!

The version detection and routing logic properly handles OpenAPI 3.x, Swagger 2.0, and provides a fallback for ambiguous cases.


1176-1228: LGTM!

The OpenAPI 3.x parsing correctly extracts API metadata, operations, and backend services. Validation of required fields is handled upstream by ValidateOpenAPIDefinition, as confirmed in past review comments.


1230-1267: LGTM!

The Swagger 2.0 parsing correctly extracts API metadata and converts Swagger-specific host/basePath/schemes into backend services. Validation is handled upstream.


1269-1293: LGTM!

The fallback parsing logic appropriately tries both OpenAPI 3.x and Swagger 2.0, providing comprehensive error messages when both fail.


1295-1347: LGTM!

The operation extraction properly handles all HTTP methods and creates well-formed Operation DTOs with appropriate defaults for authentication and policies.


1349-1401: LGTM!

The Swagger 2.0 operation extraction mirrors the OpenAPI 3.x implementation and correctly handles the supported HTTP methods.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bacff2e and 3c65f13.

📒 Files selected for processing (5)
  • platform-api/src/internal/dto/openapi.go (1 hunks)
  • platform-api/src/internal/handler/api.go (2 hunks)
  • platform-api/src/internal/service/api.go (2 hunks)
  • platform-api/src/internal/utils/api.go (2 hunks)
  • platform-api/src/resources/openapi.yaml (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: thivindu
Repo: wso2/api-platform PR: 142
File: platform-api/src/resources/openapi.yaml:905-969
Timestamp: 2025-11-12T08:52:52.909Z
Learning: In the wso2/api-platform repository, the team follows an API-first development approach where OpenAPI specs may document planned features before backend implementation is complete, allowing frontend development to proceed against the intended API contract without requiring changes later.
📚 Learning: 2025-11-08T13:06:22.133Z
Learnt from: thivindu
Repo: wso2/api-platform PR: 110
File: platform-api/src/internal/service/api.go:432-476
Timestamp: 2025-11-08T13:06:22.133Z
Learning: In the platform-api Go codebase (file: platform-api/src/internal/service/api.go), the DeployAPIRevision method is designed to automatically create API-gateway associations during deployment if they don't already exist. There is no requirement that associations must pre-exist before deployment; the system checks for existing associations and creates them on-the-fly as needed.

Applied to files:

  • platform-api/src/internal/service/api.go
🧬 Code graph analysis (3)
platform-api/src/internal/service/api.go (2)
platform-api/src/internal/dto/openapi.go (2)
  • ValidateOpenAPIRequest (27-30)
  • OpenAPIValidationResponse (33-37)
platform-api/src/internal/dto/api.go (1)
  • API (25-51)
platform-api/src/internal/handler/api.go (2)
platform-api/src/internal/utils/error.go (1)
  • NewErrorResponse (28-37)
platform-api/src/internal/dto/openapi.go (1)
  • ValidateOpenAPIRequest (27-30)
platform-api/src/internal/utils/api.go (2)
platform-api/src/internal/dto/api.go (5)
  • API (25-51)
  • Operation (134-138)
  • OperationRequest (141-148)
  • AuthenticationConfig (157-160)
  • Policy (163-166)
platform-api/src/internal/dto/backend_service.go (2)
  • BackendService (23-36)
  • BackendEndpoint (39-45)
🔇 Additional comments (9)
platform-api/src/internal/handler/api.go (1)

771-811: LGTM! Handler implementation is solid.

The multipart form handling is correct with proper file cleanup via defer, reasonable size limits, and appropriate validation. The prioritization of file over URL (when both are provided) aligns with the PR objectives.

platform-api/src/internal/dto/openapi.go (1)

1-37: LGTM! DTOs are well-structured.

The request and response structures properly support both URL and file-based OpenAPI validation with clear documentation and appropriate field types.

platform-api/src/internal/service/api.go (1)

1318-1378: LGTM! Service method handles validation flow correctly.

The implementation properly orchestrates URL fetching, file reading, validation, and parsing with appropriate error handling and resource cleanup.

platform-api/src/resources/openapi.yaml (2)

268-297: LGTM! Endpoint definition aligns with implementation.

The OpenAPI validation endpoint is properly documented with correct request/response schemas and multipart form data handling.


2552-2634: LGTM! Schemas are well-defined.

The ValidateOpenAPIRequest and OpenAPIValidationResponse schemas correctly model the validation flow with appropriate constraints (anyOf for mutual exclusivity) and field requirements.

platform-api/src/internal/utils/api.go (4)

1146-1170: LGTM! ParseAPIDefinition orchestrates parsing correctly.

The method properly handles version detection and delegates to appropriate parsers for OpenAPI 3.x and Swagger 2.0 with fallback logic.


1172-1224: LGTM! OpenAPI 3.x parsing extracts metadata correctly.

The method properly builds the OpenAPI 3.x model, extracts basic info, operations, and backend services from the document structure.


1226-1263: LGTM! Swagger 2.0 parsing handles legacy format correctly.

The method appropriately builds the Swagger 2.0 model and converts host/basePath/schemes to backend services.


1291-1397: LGTM! Operation extraction handles all HTTP methods.

Both V3 and V2 path extraction methods correctly iterate through path items and extract operations for all supported HTTP methods.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
platform-api/src/internal/utils/api.go (2)

1295-1347: Consider generating default names for operations with empty summaries.

If operation.Summary is empty, the resulting operation will have an empty Name field. This could cause issues in the UI or downstream processing.

Consider generating a default name from the method and path:

+      operationName := operation.Summary
+      if operationName == "" {
+        operationName = fmt.Sprintf("%s %s", method, path)
+      }
+
       op := dto.Operation{
-        Name:        operation.Summary,
+        Name:        operationName,
         Description: operation.Description,

1349-1401: Consider generating default names for operations with empty summaries.

Same issue as extractOperationsFromV3Paths: if operation.Summary is empty, the operation will have an empty Name field.

Apply the same fix as suggested for the V3 version:

+      operationName := operation.Summary
+      if operationName == "" {
+        operationName = fmt.Sprintf("%s %s", method, path)
+      }
+
       op := dto.Operation{
-        Name:        operation.Summary,
+        Name:        operationName,
         Description: operation.Description,
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3c65f13 and 40cfb53.

📒 Files selected for processing (1)
  • platform-api/src/internal/utils/api.go (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: thivindu
Repo: wso2/api-platform PR: 142
File: platform-api/src/resources/openapi.yaml:905-969
Timestamp: 2025-11-12T08:52:52.909Z
Learning: In the wso2/api-platform repository, the team follows an API-first development approach where OpenAPI specs may document planned features before backend implementation is complete, allowing frontend development to proceed against the intended API contract without requiring changes later.
🧬 Code graph analysis (1)
platform-api/src/internal/utils/api.go (2)
platform-api/src/internal/dto/api.go (5)
  • API (25-51)
  • Operation (134-138)
  • OperationRequest (141-148)
  • AuthenticationConfig (157-160)
  • Policy (163-166)
platform-api/src/internal/dto/backend_service.go (2)
  • BackendService (23-36)
  • BackendEndpoint (39-45)
🔇 Additional comments (3)
platform-api/src/internal/utils/api.go (3)

1127-1148: LGTM! Timeout and error handling implemented correctly.

The previous feedback regarding timeout has been addressed. The function now uses a 30-second timeout and properly handles errors and response reading.


1150-1174: LGTM! Well-structured parsing entry point.

The version-based routing with a fallback mechanism is a good approach for handling different OpenAPI/Swagger versions.


1269-1293: LGTM! Robust fallback mechanism.

The function correctly attempts both OpenAPI 3.x and Swagger 2.0 parsing and provides clear error messages if both fail.

return response, nil
}

response.IsAPIDefinitionValid = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sets IsAPIDefinitionValid: true after successful syntax validation.
However, if metadata parsing fails, it still returns true but includes error details.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed via - 7694a6e

content, err = s.apiUtil.FetchOpenAPIFromURL(req.URL)
if err != nil {
response.Errors = append(response.Errors, fmt.Sprintf("failed to fetch OpenAPI from URL: %s", err.Error()))
return response, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When both URL and file are provided, the logic stops and returns immediately if the URL fetch fails, without attempting to read from the file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed via - 7694a6e

@thivindu thivindu merged commit dd8c28a into wso2:main Nov 19, 2025
2 checks passed
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.

Implement OpenAPI definition validation

3 participants