Add OpenAPI spec and Swagger UI docs for Vehicle collection and shop services
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fe9ZVw7Q7JrMz1hgS2rwna
This commit is contained in:
commit
dfd1f365de
511
openapi/openapi.yaml
Normal file
511
openapi/openapi.yaml
Normal file
@ -0,0 +1,511 @@
|
|||||||
|
openapi: 3.0.3
|
||||||
|
info:
|
||||||
|
title: Vehicle Collection API
|
||||||
|
version: "1.0.0"
|
||||||
|
description: >
|
||||||
|
Набор из двух веб-сервисов: сервис управления коллекцией объектов Vehicle
|
||||||
|
и сервис /shop, реализующий дополнительные операции над этой коллекцией
|
||||||
|
через вызовы API первого сервиса.
|
||||||
|
license:
|
||||||
|
name: Учебный материал (лабораторная работа по курсу СОА)
|
||||||
|
servers:
|
||||||
|
- url: http://127.0.0.1:8080
|
||||||
|
description: Сервер для разработки и тестирования
|
||||||
|
tags:
|
||||||
|
- name: Vehicles
|
||||||
|
description: Первый веб-сервис — управление коллекцией объектов Vehicle
|
||||||
|
- name: Shop
|
||||||
|
description: Второй веб-сервис (/shop) — дополнительные операции над Vehicle
|
||||||
|
security: []
|
||||||
|
|
||||||
|
paths:
|
||||||
|
/api/vehicles:
|
||||||
|
post:
|
||||||
|
tags: [Vehicles]
|
||||||
|
operationId: createVehicle
|
||||||
|
summary: Добавить новый элемент в коллекцию
|
||||||
|
description: >
|
||||||
|
Создаёт новый объект Vehicle. Поля id и creationDate генерируются
|
||||||
|
сервисом автоматически и в теле запроса не передаются.
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/VehicleInput'
|
||||||
|
responses:
|
||||||
|
'201':
|
||||||
|
description: Объект успешно создан
|
||||||
|
headers:
|
||||||
|
Location:
|
||||||
|
description: URL созданного объекта
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Vehicle'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/BadRequest'
|
||||||
|
get:
|
||||||
|
tags: [Vehicles]
|
||||||
|
operationId: getVehicles
|
||||||
|
summary: Получить массив элементов коллекции
|
||||||
|
description: >
|
||||||
|
Возвращает элементы коллекции постранично. Поддерживает сортировку
|
||||||
|
по любой комбинации полей (параметр sort) и фильтрацию по любой
|
||||||
|
комбинации полей (параметр filter). Все параметры операции
|
||||||
|
передаются в URL запроса (query-параметры).
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/PageNumber'
|
||||||
|
- $ref: '#/components/parameters/PageSize'
|
||||||
|
- $ref: '#/components/parameters/Sort'
|
||||||
|
- $ref: '#/components/parameters/Filter'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Страница результатов выборки
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/VehiclePage'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/BadRequest'
|
||||||
|
|
||||||
|
/api/vehicles/{id}:
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/VehicleId'
|
||||||
|
get:
|
||||||
|
tags: [Vehicles]
|
||||||
|
operationId: getVehicleById
|
||||||
|
summary: Получить элемент коллекции по ИД
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Найденный объект
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Vehicle'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
put:
|
||||||
|
tags: [Vehicles]
|
||||||
|
operationId: updateVehicle
|
||||||
|
summary: Обновить элемент коллекции
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/VehicleInput'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Объект обновлён
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Vehicle'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/BadRequest'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
delete:
|
||||||
|
tags: [Vehicles]
|
||||||
|
operationId: deleteVehicle
|
||||||
|
summary: Удалить элемент коллекции
|
||||||
|
responses:
|
||||||
|
'204':
|
||||||
|
description: Объект удалён
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/api/vehicles/by-type/{type}:
|
||||||
|
delete:
|
||||||
|
tags: [Vehicles]
|
||||||
|
operationId: deleteVehiclesByType
|
||||||
|
summary: Удалить все объекты с заданным значением поля type
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/VehicleTypePath'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Результат удаления
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/DeletionResult'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/BadRequest'
|
||||||
|
|
||||||
|
/api/vehicles/by-type/{type}/any:
|
||||||
|
delete:
|
||||||
|
tags: [Vehicles]
|
||||||
|
operationId: deleteOneVehicleByType
|
||||||
|
summary: Удалить один (любой) объект с заданным значением поля type
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/VehicleTypePath'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Удалённый объект
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Vehicle'
|
||||||
|
'404':
|
||||||
|
description: Объектов с указанным значением type не найдено
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
|
||||||
|
/api/vehicles/count/fuel-type-less-than/{fuelType}:
|
||||||
|
get:
|
||||||
|
tags: [Vehicles]
|
||||||
|
operationId: countVehiclesByFuelTypeLessThan
|
||||||
|
summary: Вернуть количество объектов, у которых fuelType меньше заданного
|
||||||
|
description: >
|
||||||
|
Значения FuelType сравниваются по порядку их объявления в перечислении
|
||||||
|
(ALCOHOL < MANPOWER < PLASMA < ANTIMATTER). Объекты с fuelType = null
|
||||||
|
в сравнении не участвуют и не учитываются в результате.
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/FuelTypePath'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Количество подходящих объектов
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/CountResult'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/BadRequest'
|
||||||
|
|
||||||
|
/shop/fix-distance/{vehicle-id}:
|
||||||
|
post:
|
||||||
|
tags: [Shop]
|
||||||
|
operationId: fixDistance
|
||||||
|
summary: "\"Скрутить\" счётчик пробега транспортного средства до нуля"
|
||||||
|
description: >
|
||||||
|
Обращается к API первого сервиса и обнуляет счётчик пробега
|
||||||
|
транспортного средства с заданным id.
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/ShopVehicleId'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Счётчик пробега обнулён
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ActionResult'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/shop/add-wheels/{vehicle-id}/{number-of-wheels}:
|
||||||
|
post:
|
||||||
|
tags: [Shop]
|
||||||
|
operationId: addWheels
|
||||||
|
summary: Добавить транспортному средству указанное число колёс
|
||||||
|
description: >
|
||||||
|
Обращается к API первого сервиса и увеличивает число колёс
|
||||||
|
транспортного средства с заданным id на указанное значение.
|
||||||
|
parameters:
|
||||||
|
- $ref: '#/components/parameters/ShopVehicleId'
|
||||||
|
- $ref: '#/components/parameters/NumberOfWheels'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Колёса добавлены
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ActionResult'
|
||||||
|
'400':
|
||||||
|
$ref: '#/components/responses/BadRequest'
|
||||||
|
'404':
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
components:
|
||||||
|
parameters:
|
||||||
|
VehicleId:
|
||||||
|
name: id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Идентификатор объекта Vehicle
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
minimum: 1
|
||||||
|
|
||||||
|
ShopVehicleId:
|
||||||
|
name: vehicle-id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Идентификатор транспортного средства
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
minimum: 1
|
||||||
|
|
||||||
|
NumberOfWheels:
|
||||||
|
name: number-of-wheels
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Число колёс, которое нужно добавить
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
minimum: 1
|
||||||
|
|
||||||
|
VehicleTypePath:
|
||||||
|
name: type
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Значение поля type
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/VehicleType'
|
||||||
|
|
||||||
|
FuelTypePath:
|
||||||
|
name: fuelType
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: Значение поля fuelType, с которым сравниваются объекты коллекции
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/FuelType'
|
||||||
|
|
||||||
|
PageNumber:
|
||||||
|
name: pageNumber
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: Порядковый номер выводимой страницы, нумерация начинается с 1
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
minimum: 1
|
||||||
|
default: 1
|
||||||
|
|
||||||
|
PageSize:
|
||||||
|
name: pageSize
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: Размер страницы (количество элементов на странице)
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
minimum: 1
|
||||||
|
default: 10
|
||||||
|
|
||||||
|
Sort:
|
||||||
|
name: sort
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: >
|
||||||
|
Правило сортировки в формате "поле,направление", где направление —
|
||||||
|
asc или desc (по умолчанию asc). Параметр можно указать несколько
|
||||||
|
раз, чтобы отсортировать по нескольким полям сразу — порядок
|
||||||
|
повторений задаёт приоритет полей. Допустимые имена полей: id, name,
|
||||||
|
coordinates.x, coordinates.y, creationDate, enginePower, type,
|
||||||
|
fuelType.
|
||||||
|
style: form
|
||||||
|
explode: true
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
pattern: '^(id|name|coordinates\.x|coordinates\.y|creationDate|enginePower|type|fuelType)(,(asc|desc))?$'
|
||||||
|
example: ["name,asc"]
|
||||||
|
|
||||||
|
Filter:
|
||||||
|
name: filter
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: >
|
||||||
|
Условие фильтрации в формате "поле:оператор:значение". Поддерживаемые
|
||||||
|
операторы: eq, ne, gt, gte, lt, lte, like (like — только для строковых
|
||||||
|
полей, подстрока без учёта регистра). Параметр можно указать
|
||||||
|
несколько раз — все условия объединяются по И (AND), что позволяет
|
||||||
|
фильтровать по любой комбинации полей. Для проверки на отсутствие
|
||||||
|
значения используется литерал null, например enginePower:eq:null.
|
||||||
|
style: form
|
||||||
|
explode: true
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
example: ["type:eq:PLANE"]
|
||||||
|
|
||||||
|
responses:
|
||||||
|
NotFound:
|
||||||
|
description: Объект с указанным идентификатором не найден
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
BadRequest:
|
||||||
|
description: >
|
||||||
|
Переданные данные нарушают ограничения целостности, заданные на
|
||||||
|
уровне класса, либо параметры запроса имеют неверный формат
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
|
||||||
|
schemas:
|
||||||
|
VehicleType:
|
||||||
|
type: string
|
||||||
|
enum: [PLANE, BOAT, SHIP]
|
||||||
|
xml:
|
||||||
|
name: VehicleType
|
||||||
|
|
||||||
|
FuelType:
|
||||||
|
type: string
|
||||||
|
enum: [ALCOHOL, MANPOWER, PLASMA, ANTIMATTER]
|
||||||
|
xml:
|
||||||
|
name: FuelType
|
||||||
|
|
||||||
|
Coordinates:
|
||||||
|
type: object
|
||||||
|
required: [x, y]
|
||||||
|
properties:
|
||||||
|
x:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
y:
|
||||||
|
type: number
|
||||||
|
format: float
|
||||||
|
exclusiveMinimum: true
|
||||||
|
minimum: -27
|
||||||
|
xml:
|
||||||
|
name: Coordinates
|
||||||
|
|
||||||
|
Vehicle:
|
||||||
|
type: object
|
||||||
|
required: [id, name, coordinates, creationDate]
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
minimum: 1
|
||||||
|
readOnly: true
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
minLength: 1
|
||||||
|
coordinates:
|
||||||
|
$ref: '#/components/schemas/Coordinates'
|
||||||
|
creationDate:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
readOnly: true
|
||||||
|
enginePower:
|
||||||
|
type: number
|
||||||
|
format: double
|
||||||
|
nullable: true
|
||||||
|
exclusiveMinimum: true
|
||||||
|
minimum: 0
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/VehicleType'
|
||||||
|
fuelType:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/FuelType'
|
||||||
|
xml:
|
||||||
|
name: Vehicle
|
||||||
|
|
||||||
|
VehicleInput:
|
||||||
|
type: object
|
||||||
|
required: [name, coordinates]
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
minLength: 1
|
||||||
|
coordinates:
|
||||||
|
$ref: '#/components/schemas/Coordinates'
|
||||||
|
enginePower:
|
||||||
|
type: number
|
||||||
|
format: double
|
||||||
|
nullable: true
|
||||||
|
exclusiveMinimum: true
|
||||||
|
minimum: 0
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/VehicleType'
|
||||||
|
fuelType:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/components/schemas/FuelType'
|
||||||
|
xml:
|
||||||
|
name: Vehicle
|
||||||
|
|
||||||
|
VehiclePage:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
pageNumber:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
pageSize:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
totalElements:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
totalPages:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
items:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Vehicle'
|
||||||
|
xml:
|
||||||
|
name: vehicle
|
||||||
|
wrapped: true
|
||||||
|
xml:
|
||||||
|
name: VehiclePage
|
||||||
|
|
||||||
|
DeletionResult:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
deletedCount:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
xml:
|
||||||
|
name: DeletionResult
|
||||||
|
|
||||||
|
CountResult:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
count:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
xml:
|
||||||
|
name: CountResult
|
||||||
|
|
||||||
|
ActionResult:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
vehicleId:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
xml:
|
||||||
|
name: ActionResult
|
||||||
|
|
||||||
|
Error:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
timestamp:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
status:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
error:
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
path:
|
||||||
|
type: string
|
||||||
|
xml:
|
||||||
|
name: Error
|
||||||
24
openapi/swagger-ui/index.html
Normal file
24
openapi/swagger-ui/index.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Vehicle Collection API — документация</title>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="swagger-ui"></div>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
||||||
|
<script>
|
||||||
|
window.onload = function () {
|
||||||
|
SwaggerUIBundle({
|
||||||
|
url: "../openapi.yaml",
|
||||||
|
dom_id: "#swagger-ui",
|
||||||
|
presets: [
|
||||||
|
SwaggerUIBundle.presets.apis,
|
||||||
|
SwaggerUIBundle.SwaggerUIStandalonePreset
|
||||||
|
]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
x
Reference in New Issue
Block a user