tazatechnology / openapi_spec

Dart based OpenAPI specification generator and parser
BSD 3-Clause "New" or "Revised" License
9 stars 6 forks source link

Add CLI and SchemaCentralizer #49

Closed dickermoshe closed 7 months ago

dickermoshe commented 7 months ago

2 Changes:

Adds a CLI, pretty simple to use.

Adds a SchemaCentralizer which moves all complex schemas to the components section. Before this, it would generate dynamic for anything not declared in components. This is only ran when using the CLI.

Addresses Issue https://github.com/tazatechnology/openapi_spec/issues/48

walsha2 commented 7 months ago

@dickermoshe good stuff! Let me take a look and mess with this a bit.

Do you have some example specs that make use of these new changes? Can you share the spec (or an abridged version) and the before/after resulting code gen?

dickermoshe commented 7 months ago

Seems that I broke it right before pushing it! I'll ping you when I've got it working again

dickermoshe commented 7 months ago

@walsha2

Fixed the bug!

Here is a full example.

Initial Schema

``` openapi: 3.1.0 info: title: Swagger Petstore - OpenAPI 3.1 contact: email: apiteam@swagger.io license: name: Apache 2.0 url: http://www.apache.org/licenses/LICENSE-2.0.html version: 1.0.11 externalDocs: description: Find out more about Swagger url: http://swagger.io servers: - url: https://petstore3.swagger.io/api/v3 paths: /pet: put: tags: - pet summary: Update an existing pet description: Update an existing pet by Id operationId: updatePet parameters: - name: status in: query description: Status values that need to be considered for filter schema: required: - name - photoUrls type: object properties: id: type: integer format: int64 examples: [10] name: type: string examples: [doggie] photoUrls: type: array xml: wrapped: true items: type: string xml: name: photoUrl status: type: string description: pet status in the store enum: - available - pending - sold requestBody: description: Update an existent pet in the store content: application/json: schema: required: - name - photoUrls type: object properties: id: type: integer format: int64 examples: [10] name: type: string examples: [doggie] photoUrls: type: array xml: wrapped: true items: type: string xml: name: photoUrl status: type: string description: pet status in the store enum: - available - pending - sold required: true responses: '200': description: Successful operation content: application/json: schema: required: - name - photoUrls type: object properties: id: type: integer format: int64 examples: [10] name: type: string examples: [doggie] photoUrls: type: array xml: wrapped: true items: type: string xml: name: photoUrl status: type: string description: pet status in the store enum: - available - pending - sold ```

Before:

  Future<Map<String, dynamic>> updatePet({  //<< No Type!
    Map<String, dynamic>? status, //<< No Type!
    required Map<String, dynamic> request, // << No Type!
  }) async {
    final r = await makeRequest(
      baseUrl: 'https://petstore3.swagger.io/api/v3',
      path: '/pet',
      method: HttpMethod.put,
      isMultipart: false,
      requestType: 'application/json',
      responseType: 'application/json',
      body: request,
      queryParams: {
        if (status != null) 'status': status,
      },
    );
    return Map<String, dynamic>.from(_jsonDecode(r));
  }

After:

  Future<UpdatePetResponse> updatePet({
    UpdatePetStatus? status,
    required UpdatePetRequestBody request,
  }) async {
    final r = await makeRequest(
      baseUrl: 'https://petstore3.swagger.io/api/v3',
      path: '/pet',
      method: HttpMethod.put,
      isMultipart: false,
      requestType: 'application/json',
      responseType: 'application/json',
      body: request,
      queryParams: {
        if (status != null) 'status': status,
      },
    );
    return UpdatePetResponse.fromJson(_jsonDecode(r));
  }

The really cool part of your package is that I can export what the schema looks like after validation. I converted it to yaml so it's easier to compare.

Exported Schema

``` openapi: 3.1.0 info: title: Swagger Petstore - OpenAPI 3.1 contact: email: apiteam@swagger.io license: name: Apache 2.0 url: http://www.apache.org/licenses/LICENSE-2.0.html version: 1.0.11 externalDocs: description: Find out more about Swagger url: http://swagger.io servers: - url: https://petstore3.swagger.io/api/v3 paths: /pet: put: tags: - pet summary: Update an existing pet description: Update an existing pet by Id operationId: updatePet parameters: - name: status in: query description: Status values that need to be considered for filter schema: $ref: '#/components/schemas/UpdatePetStatus' requestBody: description: Update an existent pet in the store required: true content: application/json: schema: $ref: '#/components/schemas/UpdatePetRequestBody' responses: '200': description: Successful operation content: application/json: schema: $ref: '#/components/schemas/UpdatePetResponse' components: schemas: UpdatePetRequestBody: required: - name - photoUrls type: object properties: id: type: integer format: int64 name: type: string photoUrls: type: array xml: wrapped: true items: type: string xml: name: photoUrl status: type: string description: pet status in the store enum: - available - pending - sold UpdatePetResponse: required: - name - photoUrls type: object properties: id: type: integer format: int64 name: type: string photoUrls: type: array xml: wrapped: true items: type: string xml: name: photoUrl status: type: string description: pet status in the store enum: - available - pending - sold UpdatePetStatus: required: - name - photoUrls type: object properties: id: type: integer format: int64 name: type: string photoUrls: type: array xml: wrapped: true items: type: string xml: name: photoUrl status: type: string description: pet status in the store enum: - available - pending - sold ```

dickermoshe commented 7 months ago

I'm down to write test or make any refactors if you want

dickermoshe commented 7 months ago

Just curious, why don't you use dio?

walsha2 commented 7 months ago

I'm down to write test or make any refactors if you want

Can you rebase using the latest main branch? I needed to fix a missed unit testing issue. It is now fixed on main.

Once you rebase, there are a few issues that need to resolved or clarified. See file change comments.

walsha2 commented 7 months ago

Just curious, why don't you use dio?

Simple http is a first party package from the Dart core team, dio is not. http does everything that is required for standard REST API operations, no need to use another third party package.

dickermoshe commented 7 months ago

I pulled all of the openapi specs from the openapi-generator package and ran the generator on all of them found some small bugs, I'll file issues later.

walsha2 commented 7 months ago

found some small bugs, I'll file issues later.

Bugs related to the centralize step or to the existing generator? FWIW all of the sample openapi specs are in the test/oas_examples/ directory and are tested.

dickermoshe commented 7 months ago

The existing code, not the centralizer.

walsha2 commented 7 months ago

The existing code, not the centralizer.

Great! Yes, please file the issues (sooner the better) and I can take a look. Would prefer that those are fixed before next release.