W moim „uproszczonym” interfejsie API wszystkie odpowiedzi są wyprowadzane ( dziedziczone ) z podstawowej klasy „odpowiedzi”. Klasa odpowiedzi składa się z nagłówka wypełnionego metadanymi oraz treści zawierającej podstawowe dane, o które prosi użytkownik. Odpowiedź (w formacie JSON) jest ułożona w taki sposób, że wszystkie metadane znajdują się na pierwszej „warstwie”, a treść jest pojedynczym atrybutem o nazwie „body”.
response
|--metadata attribute 1 (string/int/object)
|--metadata attribute 2 (string/int/object)
|--body (object)
|--body attribute 1 (string/int/object)
|--body attribute 2 (string/int/object)
Próbowałem zdefiniować tę relację z zachwytem za pomocą następującego kodu JSON:
{
...
"definitions": {
"response": {
"allOf": [
{
"$ref": "#/definitions/response_header"
},
{
"properties": {
"body": {
"description": "The body of the response (not metadata)",
"schema": {
"$ref": "#/definitions/response_body"
}
}
}
}
]
},
"response_header": {
"type": "object",
"required": [
"result"
],
"properties": {
"result": {
"type": "string",
"description": "value of 'success', for a successful response, or 'error' if there is an error",
"enum": [
"error",
"success"
]
},
"message": {
"type": "string",
"description": "A suitable error message if something went wrong."
}
}
},
"response_body": {
"type": "object"
}
}
}
Następnie próbuję utworzyć różne odpowiedzi, tworząc różne klasy treści / nagłówka, które dziedziczą po treści / nagłówku, a następnie tworzę klasy odpowiedzi potomnych, które składają się z odpowiednich klas nagłówka / treści (pokazane w kodzie źródłowym na dole). Jestem jednak pewien, że albo jest to niewłaściwy sposób robienia rzeczy, albo że moja implementacja jest nieprawidłowa. Nie udało mi się znaleźć przykładu dziedziczenia w specyfikacji Swagger 2.0 (pokazanej poniżej), ale znalazłem przykład kompozycji .
Jestem prawie pewien, że ten „dyskryminator” ma dużą rolę do odegrania, ale nie wiem, co powinienem zrobić.
Pytanie
Czy ktoś mógłby mi pokazać, jak należy zaimplementować kompozycję + dziedziczenie w swagger 2.0 (JSON), najlepiej "naprawiając" mój przykładowy kod poniżej. Byłoby również świetnie, gdybym mógł określić klasę ErrorResponse, która dziedziczy z odpowiedzi, w której atrybut „result” w nagłówku jest zawsze ustawiony na „error”.
{
"swagger": "2.0",
"info": {
"title": "Test API",
"description": "Request data from the system.",
"version": "1.0.0"
},
"host": "xxx.xxx.com",
"schemes": [
"https"
],
"basePath": "/",
"produces": [
"application/json"
],
"paths": {
"/request_filename": {
"post": {
"summary": "Request Filename",
"description": "Generates an appropriate filename for a given data request.",
"responses": {
"200": {
"description": "A JSON response with the generated filename",
"schema": {
"$ref": "#/definitions/filename_response"
}
}
}
}
}
},
"definitions": {
"response": {
"allOf": [
{
"$ref": "#/definitions/response_header"
},
{
"properties": {
"body": {
"description": "The body of the response (not metadata)",
"schema": {
"$ref": "#/definitions/response_body"
}
}
}
}
]
},
"response_header": {
"type": "object",
"required": [
"result"
],
"properties": {
"result": {
"type": "string",
"description": "value of 'success', for a successful response, or 'error' if there is an error",
"enum": [
"error",
"success"
]
},
"message": {
"type": "string",
"description": "A suitable error message if something went wrong."
}
}
},
"response_body": {
"type": "object"
},
"filename_response": {
"extends": "response",
"allOf": [
{
"$ref": "#definitions/response_header"
},
{
"properties": {
"body": {
"schema": {
"$ref": "#definitions/filename_response_body"
}
}
}
}
]
},
"filename_response_body": {
"extends": "#/definitions/response_body",
"properties": {
"filename": {
"type": "string",
"description": "The automatically generated filename"
}
}
}
}
}
Aktualizacja diagramu
Aby spróbować wyjaśnić, czego chcę, utworzyłem poniżej bardzo podstawowy diagram, który ma na celu pokazanie, że wszystkie odpowiedzi są instancjami obiektu „response”, który został zbudowany przez (kompozycja) przy użyciu dowolnej kombinacji obiektów response_header i response_body. Obiekty response_header i response_body mogą być rozszerzone i wstawione do dowolnego obiektu odpowiedzi, co ma miejsce w przypadku pliku nazwa_odpowiedzi, która używa elementu potomnego filename_response_body z podstawowej klasy response_body. Zarówno błędy, jak i pomyślne odpowiedzi używają obiektu „odpowiedź”.