ballerina-platform / ballerina-library

The Ballerina Library
https://ballerina.io/learn/api-docs/ballerina/
Apache License 2.0
136 stars 64 forks source link

[Proposal] Convert the OAS to Ballerina-friendly naming conventions #6867

Closed lnash94 closed 1 week ago

lnash94 commented 3 months ago

Summary

The OpenAPI Specification (OAS) is a widely adopted standard for defining RESTful APIs. However, the naming conventions used in OAS often differ from those preferred in Ballerina. To enhance the usability and readability of OAS definitions in Ballerina, it is essential to adapt the OAS naming conventions to align with Ballerina's conventions. This proposal outlines the approach for modifying the OAS to conform to Ballerina naming conventions.

Goals

Motivation

[1] Referring to the below OAS sample:

openapi: "3.0.0"
info:
  version: v3
  title: Karbon API 3.0
servers:
  - url: http://localhost:9090/v1
paths:
  /customer/groups:
    get:
      …
      parameters:
        - name: "customer-group" \\query param
          in: query
          schema:
            type: string
      responses:
        '200':
          description: successful
          content:
            "application/json":
              schema:
                $ref: "#/components/schemas/karbon.Api.Contacts.V2.ClientGroupSummaryDTO"
components:
  schemas:
    karbon.Api.Contacts.V2.ClientGroupSummaryDTO:  \\schema types
      type: object
      properties:
        full-name:  \\property-name
          type: string
        phone-number:  \\property-name
          type: string

Generated Ballerina Code:

public type karbon\.Api\.Contacts\.V2\.ClientGroupSummaryDTO record { 
     string full\-name; 
     string phone\-number; 
}
…
resource isolated function get customer/groups(map<string|string[]> headers = {}, *GetClientQueries queries) returns karbon\.Api\.Contacts\.V2\.ClientGroupSummaryDTO|error {
       ...
   }
}

However, when using this generated record, users may face code readability issues. The escaped characters make the code harder to read and understand. This can lead to confusion and potential mistakes during development. By addressing this issue we aim to generate Ballerina-friendly code using OAS by applying modifications to the user-given OAS.

Description

The proposed solution is modifying the OAS with the Ballerina-friendly naming conventions for the below-mentioned areas,

openapi: "3.0.0"
info:
 ...
paths:
  /customer/groups:
    get:
      …
      parameters:
        - name: "customer-group"
          x-ballerina-name: “customerGroup”   <--- query name extension
          in: query
          schema:
            type: string
      responses:
        '200':
          description: successful
          content:
            "application/json":
              schema:
                $ref: "#/components/schemas/KarbonApiContactsV2ClientGroupSummaryDTO"
components:
 schemas:
   KarbonApiContactsV2ClientGroupSummaryDTO: // Type Name
     type: object
     properties:
       full-name: //property name
         type: string
         x-ballerina-name: fullName          <--property name extension 
       phone-number:
         type: string
         x-ballerina-name: phoneNumber  

We are providing two options to the user as a deliverable,

  1. If the user is interested in the returned OAS as a deliverable, we introduce a sub-command to return the modified OAS mentioned above.[2]

$ bal openapi sanitize \<yaml file>

  1. When the user needs to generate a client/service which engages that modified OAS, deliverable is client /service Ballerina code.
    • When we use the modified OAS according to the Ballerina conventions, we will generate the following Ballerina code as a client.
type KarbonApiContactsV2ClientGroupSummaryDTO record { 
    @http:Field: {name: "field-name"}
        string fullName; 
    @http:Field: {name: "phone-number" }
         string phoneNumber; 
}
resource isolated function get customer/groups(map<string|string[]> headers = {}, *GetClientQueries queries) returns KarbonApiContactsV2ClientGroupSummaryDTO|error {
       …
   }

# Represents the Queries record for the operation
public type GetClientQueries record {
    #query annotation for the parameter 
    @http:Query{ name: "customer-group" }
    string? customerGroup?;
    //other remaining query parameters
};
lnash94 commented 1 week ago

Close this issue since all the related sub fixes are merged