-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Aligning error
mapping with spec generation for new HTTP error
structure
#5135
Comments
The Sample Ballerina service: import ballerina/http;
import ballerina/time;
import ballerina/http.httpscerr;
type Album readonly & record {|
string title;
string artist;
|};
table<Album> key(title) albums = table [
{title: "Blue Train", artist: "John Coltrane"},
{title: "Jeru", artist: "Gerry Mulligan"}
];
type ErrorBody record {
string timeStamp;
string message;
};
type ErrorHeaders record {|
string req\-id;
string error\-code;
|};
type ErrorDetail record {
*httpscerr:ErrorDetail;
ErrorBody body;
ErrorHeaders headers;
};
type Error error<ErrorDetail>;
type AlbumNotFound httpscerr:NotFoundError & Error;
type DefaultError httpscerr:DefaultStatusCodeError & Error;
service / on new http:Listener(9090) {
resource function get albums/[string title]() returns Album|AlbumNotFound {
if albums.hasKey(title) {
return albums.get(title);
}
return error AlbumNotFound("Album not found", body = {
timeStamp: time:utcToString(time:utcNow()),
message: "Album not found for title: " + title
}, headers = {
req\-id: "req001",
error\-code: "err001"
});
}
resource function get albums(string artist) returns Album[]|DefaultError {
Album[] selectedAlbums = from Album album in albums
where album.artist == artist
select album;
if selectedAlbums.length() == 0 {
return error DefaultError("No albums found for artist: " + artist, body = {
timeStamp: time:utcToString(time:utcNow()),
message: "No albums found for artist: " + artist
}, headers = {
req\-id: "req001",
error\-code: "err002"
},
statusCode = 404);
}
return selectedAlbums;
}
} Expected OpenAPI specification: openapi: 3.0.1
info:
title: Main Openapi Yaml
version: 0.1.0
servers:
- url: "{server}:{port}/"
variables:
server:
default: http://localhost
port:
default: "9090"
paths:
/albums/{title}:
get:
operationId: getAlbumsTitle
parameters:
- name: title
in: path
required: true
schema:
type: string
responses:
"200":
description: Ok
content:
application/json:
schema:
$ref: '#/components/schemas/Album'
"404":
description: NotFound
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
"400":
description: BadRequest
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorPayload'
/albums:
get:
operationId: getAlbums
parameters:
- name: artist
in: query
required: true
schema:
type: string
responses:
"200":
description: Ok
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Album'
"400":
description: BadRequest
headers:
req-id:
schema:
type: string
error-code:
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorPayload'
"default":
description: Default error response
headers:
req-id:
schema:
type: string
error-code:
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorBody'
components:
schemas:
Album:
required:
- artist
- title
type: object
properties:
title:
type: string
artist:
type: string
additionalProperties: false
ErrorBody:
required:
- timestamp
- message
type: object
properties:
timestamp:
type: string
message:
type: string
ErrorPayload:
required:
- message
- method
- path
- reason
- status
- timestamp
type: object
properties:
timestamp:
type: string
status:
type: integer
format: int64
reason:
type: string
message:
type: string
path:
type: string
method:
type: string |
Proposal: OAS mapping for HTTP status code errorsSummaryThis proposal is to add the relevant OAS response mapping for HTTP status code error return types. Goals
MotivationWhen writing HTTP services it is common to deal with errors and return the appropriate HTTP status codes. The Ballerina HTTP library provides a set of HTTP status code errors that can be returned from the service. So at runtime, the HTTP status code errors are converted to the relevant HTTP status code responses. import ballerina/http;
import ballerina/time;
import ballerina/http.httpscerr;
type Album readonly & record {|
string title;
string artist;
|};
table<Album> key(title) albums = table [
{title: "Blue Train", artist: "John Coltrane"},
{title: "Jeru", artist: "Gerry Mulligan"}
];
type ErrorBody record {
string timeStamp;
string message;
};
type ErrorHeaders record {|
string req\-id;
string error\-code;
|};
type ErrorDetail record {
*httpscerr:ErrorDetail;
ErrorBody body;
ErrorHeaders headers;
};
type Error error<ErrorDetail>;
type AlbumNotFound httpscerr:NotFoundError & Error;
service / on new http:Listener(9090) {
resource function get albums/[string title]() returns Album|AlbumNotFound {
if albums.hasKey(title) {
return albums.get(title);
}
return error AlbumNotFound("Album not found", body = {
timeStamp: time:utcToString(time:utcNow()),
message: "Album not found for title: " + title
}, headers = {
req\-id: "req001",
error\-code: "err001"
});
}
} In addition to this strict mode, where the user should create different subtypes of the HTTP status code errors, the Ballerina HTTP library provides a relaxed mode where the users can return a subtype of ...
type DefaultError httpscerr:DefaultStatusCodeError & Error;
service / on new http:Listener(9090) {
...
resource function get albums(string artist) returns Album[]|DefaultError {
Album[] selectedAlbums = from Album album in albums
where album.artist == artist
select album;
if selectedAlbums.length() == 0 {
return error DefaultError("No albums found for artist: " + artist, body = {
timeStamp: time:utcToString(time:utcNow()),
message: "No albums found for artist: " + artist
}, headers = {
req\-id: "req001",
error\-code: "err002"
},
statusCode = 404);
}
return selectedAlbums;
}
} The current OpenAPI tool generates the following response mapping for all the error types. "500":
description: InternalServerError
content:
application/json: {} Since the HTTP status code errors returned from the resource are converted to relevant HTTP status code responses at runtime, the generated OpenAPI specification should be updated with the relevant response mapping. DescriptionAs mentioned above, the purpose of this proposal is to reflect the current implementation of the HTTP status code errors in the OpenAPI specification generated by the tool. Strict mode with subtypes of HTTP status code errorsThe relevant response mapping can be generated from the following details:
Example:
Relaxed mode with
|
BallerinaCode | OpenAPI |
---|---|
...
type DefaultError
httpscerr:DefaultStatusCodeError & Error;
service / on new http:Listener(9090) {
...
resource function
get albums(string artist)
returns Album[]|DefaultError {
...
}
} |
responses:
"200":
description: Ok
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Album"
"400": # This is for the databinding errors
description: BadRequest
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorPayload"
# The response mapping for the DefaultError
"default":
description: Default error response
headers:
req\-id:
schema:
type: string
error\-code:
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorBody" |
Implemented via ballerina-platform/openapi-tools#1604 |
Description:
$Subject
Reference Issue : #4101
Describe your problem(s)
Describe your solution(s)
Related Issues (optional):
Suggested Labels (optional):
Suggested Assignees (optional):
The text was updated successfully, but these errors were encountered: