kubeshop / kusk-gateway

Kusk-gateway is an OpenAPI-driven API Gateway for Kubernetes
https://kubeshop.github.io/kusk-gateway/
MIT License
253 stars 21 forks source link

Retreive OpenAPI specifications from the upstream #952

Open kerwanp opened 1 year ago

kerwanp commented 1 year ago

A bit of context

My APIs use Swagger (in my case @nestjs/swagger) to expose their documentation. I use the generated specification to automatically generate the openapi.yaml file.

export const generateOpenapi = (document: OpenAPIObject, path: string) => {

  if (!fs.existsSync(path)) return;

  const current = YAML.parse(fs.readFileSync(path).toString());
  const target = { ...current, ...document };

  fs.writeFileSync(path, YAML.stringify(target))
};

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  app.useGlobalPipes(new ValidationPipe());

  const config = new DocumentBuilder()
    .setTitle('Auth API')
    .setDescription('The Auth API')
    .setVersion('1.0')
    .build();

  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document);

  generateOpenapi(document, 'apps/auth/openapi.yaml');

  const globalPrefix = '';
  app.setGlobalPrefix(globalPrefix);
  const port = process.env.PORT || 80;
  await app.listen(port);
  Logger.log(
    `🚀 Application is running on: http://localhost:${port}/${globalPrefix}`
  );
}

How do I do currently ?

Here is the workflow I use in development:

  1. Run the application to generate the openapi.yaml file
  2. Build a Docker image with the new version of my service
  3. Update the deployment with the new image
  4. Deploy the openapi.yaml

The enhancement

Most of restful APIs expose their OpenAPIV3 specifications and Kusk could directly gather it from the service.

I could have a simple openapi.yaml file:

x-kusk:
  upstream:
    service:
      name: auth
      namespace: default
      port: 80
    openapi:
      path: /json-doc # Upstream Route returning the OpenAPIV3 specification 

And when deploying the service, Kusk automatically merge the deployed openapi.yaml with the result of the request on x-kusk.upstream.openapi.path.

This way the ìnfo and the openapi is also gathered from the service.

Why I think this feature is important ?

It is the first time I use an API Gateway, before I was writing it myself. Everytime I was creating a new endpoint on one of my service I had to also add it to my Gateway to proxy the request.

When I checked all the API Gateway tools, it was the same result: Having to rewrite the specification of each path of each service somewhere.

Using the OpenAPI to manage the API Gateway is for me the most appropriate method. It is not because we do microservices that we do not have to follow standards. And frameworks like https://api-platform.com/ and https://nestjs.com/ provide incredible tools to create really Restful APIs

I think that this feature match completely the vision of Kusk. You have a new service serving a Restful API ? Deploy it, write few lines in a yaml file and boom, exposed.

:warning: A problem with mocks

The problem now is the mocking part, because we do not have the OpenAPIV3 specification without running the service. I currently have no idea on how to handle that. I still opened this issue in case you have ideas.