Closed lnash94 closed 2 months ago
Proposed annotation for the openapi:ResourceInfo
# This annotation represents a record for storing resource meta information.
#
# + summary - A brief summary of the resource.
# + tags - Tags associated with the resource.
# + operationId - Unique identifier for the operation.
# + example - This section contains detailed examples for responses and request bodies.
public type ResourceInformation record {|
string summary?;
string[] tags?;
string operationId?;
Examples examples?;
|};
# Represents an example of a response for a specific status code.
#
# + headers - The headers for the response.
# + mediaType - The media type of the response.
# + examples - Detailed examples of the response content.
public type ResponseExample record {
map<string> headers?;
string mediaType;
map<record {}> examples;
};
# Represents an example of a request body for a specific media type.
#
# + mediaType - The media type of the request body.
# + examples - Detailed examples of the request body content.
public type RequestExample record {
string mediaType;
map<record {}> examples;
};
# Represents examples for resource function.
#
# + response - Response examples
# + requestBody - Requst examples
public type Examples record {|
map<ResponseExample[]> response?;
RequestExample[] requestBody?;
|};
User experience
import ballerina/openapi;
service / on ep0 {
@openapi:ResourceInfo {
operationId: "operationId",
tags: ["pets", "food"],
examples: {
response: {
"200": [
{
headers: {"x-expires-after": "2024-06-01T23:59:59Z"},
mediaType: "application/json",
examples: {
"pet": {name: "Rova", age: 5}
}
}
]
},
requestBody: [
{
mediaType: "application/json",
examples: {
"pet": {name: "Tommy", age: 6}
}
}
]
}
}
resource function post pet(@http:Payload Pet body) returns Pet {
}
}
Redesigned annotation v2
# This annotation represents a record for storing resource meta information.
#
# + summary - A brief summary of the resource.
# + tags - Tags associated with the resource.
# + operationId - Unique identifier for the operation.
# + examples - This section contains detailed examples for responses and request bodies.
public type ResourceInformation record {|
string summary?;
string[] tags?;
string operationId?;
Examples examples?;
|};
# Represents an example of a response for a specific status code.
#
# + headers - The headers for the response.
# + examples - Detailed examples of the response content.
public type ResponseExample record {
map<string> headers?;
map<map<record {|record {} value;|}>> examples?;
};
# Represents an example of a request body for a specific media type.
public type RequestExamples map<anydata>;
# Represents examples for resource function.
#
# + response - Response examples
# + requestBody - Requst examples
public type Examples record {|
map<ResponseExample> response?;
RequestExamples requestBody?;
|};
public const annotation ResourceInformation ResourceInfo on object function;
Workaround done for the design: https://github.com/ballerina-platform/openapi-tools/pull/1722#issuecomment-2172419121 Related ballerina lang issue: https://github.com/ballerina-platform/ballerina-lang/issues/42933
OAS swagger allows to have only an example for payload, the annotation design below is for getting the example details
# Represents an example of a request body for a specific media type.
#<mediaType, <name, value for the examples>>
public type RequestExamples map<map<record {|record {}|string value;|}>>;
Annotation usage in ballerina service
import ballerina/http;
import ballerina/openapi;
listener http:Listener httpListener = check new (9000);
service /convert on httpListener {
@openapi:ResourceInfo {
examples: {
"requestBody": {
"application/json": {
"requestExample01": {
"value": "/Users/hansaninissanka/Documents/Ballerina_Projects/example_feature/examples.json" //with reference file
},
"requestExample02": {
"value": { // with inline value
"fromCurrancy": "LKR",
"toCurrancy": "USD"
}
}
}
}
}
}
resource function post xe_data(record{} payload) returns record {}? {
return {};
}
}
Generated OAS:
/xe_data:
post:
...
requestBody:
content:
application/json:
schema:
type: object
properties: {}
examples:
requestExample01:
value:
toAmount: 60000
fromCurrency: USD
toCurrency: LKR
fromAmount: 200
timestamp: 2024-06-14
requestExample02:
value:
fromCurrancy: LKR
toCurrancy: USD
required: true
responses:
"201":
description: Created
content:
application/json:
schema:
Meeting date: 2024/07/09 Attendees: @shafreenAnfar , @TharmiganK , @dilanSachi, @lnash94
RequestExamples
type into map<map<record {|record {} value?; string filePath?;|}>>
ResponseExample
type into
public type ResponseExample record {|
map<string> headers?;
map<map<record {|record {} value?; string filePath?;|}>> examples?;
|};
Having two optional fields value
and filePath
may enable the user to have use both at a once therefore we change it into two different record
public type ResponseExample record {|
map<string> headers?;
map<map<record {|record {} value;|}|record {|string filePath;|}>> examples?;
|};
public type RequestExamples readonly & map<map<record {|record {} value?;|}| record {| string filePath?;|}>>;
Description: This feature aims to add an example for the generated OAS. An API specification can include examples for:
Examples can be used by tools and libraries, for instance, Swagger UI auto-populates request bodies based on input schema examples, and some API mocking tools use examples to generate mock responses.
Tasks: