Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The OpenAPI introspection resource returns an incorrect specification #6511

Closed
TharmiganK opened this issue May 8, 2024 · 5 comments · Fixed by ballerina-platform/module-ballerina-http#2037

Comments

@TharmiganK
Copy link
Contributor

Description:

We can add an introspection resource to an HTTP service by adding the following OpenAPI annotation:

@openapi:ServiceInfo {
    embed: true
}

When the OpenAPI contract path is not specified in the above annotation, OpenAPI compiler plugin checks that and we generate the OpenAPI specification by passing the service declaration node to the OpenAPI tool. The generate specification is added to the http:ServiceConfig annotation via a code modifier in the OpenAPI tool. Then the HTTP compiler plugin reads that field and generate a introspection resource and inject that to the existing service.

But the issue arises with the HTTP code modifier which actually adds the @http:Payload annotation to the request payload. Since this code modifier is engaged after the OpenAPI compiler plugin, the OpenAPI tool tries to generate the specification without this specific annotation which ends up in a incorrect specification.

Steps to reproduce:

Run the following service:

import ballerina/http;
import ballerina/openapi;

type Post record {
    string text;
};

@openapi:ServiceInfo {
    embed: true
}
service /text\-processing on new http:Listener(9098) {

    resource function post api/sentiment(Post post) {}
}

Use the introspection resource to retrieve the specification:

$ curl http://localhost:9098/text-processing/openapi-doc-dygixywsw
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "Text Processing",
    "version" : "0.1.0"
  },
  "servers" : [ {
    "url" : "{server}:{port}/text-processing",
    "variables" : {
      "server" : {
        "default" : "http://localhost"
      },
      "port" : {
        "default" : "9098"
      }
    }
  } ],
  "paths" : {
    "/api/sentiment" : {
      "post" : {
        "operationId" : "postApiSentiment",
        "parameters" : [ {
          "name" : "post",
          "in" : "query",
          "required" : true,
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/Post"
              }
            }
          }
        } ],
        "responses" : {
          "202" : {
            "description" : "Accepted"
          },
          "400" : {
            "description" : "BadRequest",
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/ErrorPayload"
                }
              }
            }
          }
        }
      }
    }
  },
  "components" : {
    "schemas" : {
      "ErrorPayload" : {
        "required" : [ "message", "method", "path", "reason", "status", "timestamp" ],
        "type" : "object",
        "properties" : {
          "timestamp" : {
            "type" : "string"
          },
          "status" : {
            "type" : "integer",
            "format" : "int64"
          },
          "reason" : {
            "type" : "string"
          },
          "message" : {
            "type" : "string"
          },
          "path" : {
            "type" : "string"
          },
          "method" : {
            "type" : "string"
          }
        }
      },
      "Post" : {
        "required" : [ "text" ],
        "type" : "object",
        "properties" : {
          "text" : {
            "type" : "string"
          }
        }
      }
    }
  }
}

Note : the Post is considered as query parameter but it should be the request body.

Affected Versions:

Ballerina SwanLake Update 2201.9.0

@lnash94
Copy link
Member

lnash94 commented May 8, 2024

AFAIR code modifiers execute before compiler plugin code analyzers, and those modifiers, as well as the analyzer, cannot preserve a specific order while executing. Since both HTTP and OpenAPI plugins are code modifiers, shall we check any mechanism to guarantee that the code modification has occurred? (For example, maintaining a cache or having a private flag to the service node)

@TharmiganK
Copy link
Contributor Author

Adding @azinneera for suggestions

@azinneera
Copy link

ATM, we don't guarantee the order of execution of the modifier plugins. What is the behavior we expect here?

@TharmiganK
Copy link
Contributor Author

There is two imports openapi and http. Both have code modifiers. The requirement here is running the code modifier of the http module before running the openapi one.

@TharmiganK
Copy link
Contributor Author

We are planning to refactor the design using static resources. We need APIs to read and write the resources from compiler time. This has been tracked via: ballerina-platform/ballerina-lang#43041

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Status: Done
Development

Successfully merging a pull request may close this issue.

3 participants