samchon / nestia

NestJS Helper Libraries + TypeScript OpenAPI generator
https://nestia.io/
MIT License
1.81k stars 94 forks source link

swagger output not satisfy open api spec #1014

Closed sacru2red closed 3 weeks ago

sacru2red commented 3 weeks ago

Bug Report

I have under code

import { type OpenAPIObject, SwaggerModule } from '@nestjs/swagger'
...
const docs = require(path.resolve(__dirname, '..', '..', 'swagger', 'swagger.json'))
const assertedDocs = assert<OpenAPIObject>(docs)

It throws error

debugging: validate result ->

{
  "success": false,
  "errors": [
    {
      "path": "$input.paths[\"/admin/administrator/all\"].get.responses[\"200\"]",
      "expected": "(ReferenceObject | ResponseObject)",
      "value": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/sersControllerResponseDto"
            }
          }
        }
      }
    },

ref0: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0-rc0/versions/3.0.md#responseObject -> description is Required ref1: https://github.com/nestjs/swagger/blob/master/lib/interfaces/open-api-spec.interface.ts ref2: https://swagger.io/specification/#paths-object

  responses:
    NotFound:
      description: Entity not found.
    IllegalInput:
      description: Illegal input for operation.
    GeneralError:
      description: General Error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/GeneralError'
samchon commented 3 weeks ago

In @nestjs/swagger, how to fill the description property value?

samchon commented 3 weeks ago

I've researched many other OpenAPI documents to develop @nestia/migrate and @nestia/editor, but most of famous services have not filled the description field in both request and response bodies. Thus, I've designed both OpenApi.IOperation.IRequestBody.description and OpenApi.IOperation.IResponse.description properties as optional.

I know your approach is the exactly right way, but if I block it following the standard OpenAPI specification, most of OpenAPI documents would be disabled. For this reason, @samchon/openapi has somewhat looser type definitions and checks than the standard OpenAPI spec, such as opening fields that were clearly required but are optional.

This is the reason why I've guided to cast the @nestia/sdk generated OpenAPI document to be any.

import { NestiaSwaggerComposer } from "@nestia/sdk";
import { INestApplication } from "@nestjs/common";
import { NestFactory } from "@nestjs/core";
import { SwaggerModule } from "@nestjs/swagger";

const main = async (): Promise<void> => {
  const app: INestApplication = await NestFactory.create(ApplicationModule);
  const document = await NestiaSwaggerComposer.document(app, {
    openapi: "3.1",
    servers: [
      {
        url: "http://localhost:3000",
        description: "Localhost"
      }
    ]
  });
  SwaggerModule.setup("api", app, document as any);
  await app.listen(3_000);
};
main().catch(console.error);
samchon commented 3 weeks ago

By the way, even though many other major services are not filling the description property, I do not need to do like them.

If no @return or @returns comment exists in the controller method, I'll fill the description property as empty string "".

sacru2red commented 3 weeks ago

Thanks for quick response!

sacru2red commented 3 weeks ago

음 마지막 줄을 못보고 이슈를 닫아버렸네요. 아마? 진행하신다면 다시 오픈하셔야 할 것 같습니다ㅎㅎ..

빈 문자열로 채우는 것도 괜찮은 것 같아요. 아니면 엔티티 이름이 적당한 길이 이상이면 엔티티 이름을 박아도 되지 않을까 잠깐 생각해봤습니다.

samchon commented 3 weeks ago

Also, you don't have to validate through the OpenAPI definition of @nestia/swagger.

It's version is 3.0 only, but @nestia/sdk is supporting every versions' generation.

samchon commented 3 weeks ago

Upgrade to v3.12.2, then be fixed.