yndlingsfar / serverless-openapi-integration-helper

The plugin separates x-amazon-apigateway extension syntax from your openapi3 files
MIT License
6 stars 5 forks source link

Multiple APIs #15

Closed Kirynn closed 1 year ago

Kirynn commented 2 years ago

Just wondering if this is planned?

henhal commented 1 year ago

I was about to submit the same question (I think, there are very few details above). My use-case: I have an API which is versioned, so for example api.example.com/v1/... and api.example.com/v2/..., etc.

Each major API version has its own OpenAPI specification, which makes sense since an OpenAPI specification in fact specifies the version - it wouldn't make sense to include /v2 prefixes etc in the API specification itself.

I'm using this plugin and I love it, but realized it doesn't support multiple API specifications, meaning there's no way for me to generate one API from my-api-v1.yml + integrations/v1/ and inject the built body into one AWS::ApiGateway::RestApi resource, and to generate another API from my-api-v2.yml + integrations/v2 into another RestApi resource.

I noted that the resulting body is injected into the CF template like this:

addApiAGatewayBody(generatedApiSpecification) {
        let resources = this.serverless.service.resources.Resources;
        Object.entries(resources).forEach(([resourceName, resource]) => {
            if (resource.Type === 'AWS::ApiGateway::RestApi') {
                if (resource.hasOwnProperty('Properties') && !resource.Properties.hasOwnProperty('Body')) {
                    resource.Properties.Body = {}
                }

                resource.Properties.Body = jsYml.load(fs.readFileSync(generatedApiSpecification))
            }

            this.serverless.service.resources.Resources = resources;
        });
    }

In other words, if my template has multiple RestApi resources, each one will get the same body.

To me it seems like multiple APIs could be accomplished by allowing openApiIntegration in serverless.yml to be an array, and where each array item has the resourceName of the corresponding RestApi resource:

openApiIntegrations:
  -   inputFile: my-api-v1.yml
      package: true
      validation: true
      mapping:
        - stage: [dev, prod]
          path: integrations
      outputFile: out/my-api-v1.yml
      apiResourceName: RestApiV1
  -   inputFile: my-api-v2.yml
      package: true
      validation: true
      mapping:
        - stage: [dev, prod]
          path: integrations
      outputFile: out/my-api-v2.yml
      apiResourceName: RestApiV2

...
resources:
  Resources:
    RestApiV1:
      Type: AWS::ApiGateway::RestApi
      Properties:
        Body: ~ # auto-generated by plugin
        ...
    RestApiV2:
      Type: AWS::ApiGateway::RestApi
      Properties:
        Body: ~ # auto-generated by plugin
        ...

Would you agree? Would a PR for this be interesting? Do you see any problems with my suggested approach?

yndlingsfar commented 1 year ago

This definitely makes sense. Would you like to prepare a PR for that? Would be much appreciated Regards Daniel

henhal commented 1 year ago

Great! I'll jump right at it.

yndlingsfar commented 1 year ago

fixed :-)