В этой статье будет описана только техника хранения спецификаций и конкретные шаги по их подключению в приложении. Для упрощения здесь не будут описаны некоторые принципы важные для использования в production коммерческих проектов. Здесь совсем чуть-чуть про то почему пошли в эту историю. Ввиду некоторых проблем с доступом к документации openapi на сайте я буду оставлять ссылки на документацию в Github.  Создаём репозиторий в котором будут располагаться наши спецификации и укладываем нужные файлы в следующую структуру: repository/ - корневая директория, может иметь любое подходящее название. Здесь мы будем складывать все наши сервисы. spring-boot-openapi-generation/ - сервис, над API которого мы сейчас работаем. 1.0.0/ - конкретная версия API. По мере доработок сервиса рядом будут создаваться 1.0.1 и последующие версии API. api.yaml - файл первого уровня контракта, в котором описаны эндпоинты, теги и id. models/ - директория, в которой будут располагаться реализация моделей из api.yaml components.yaml - файл второго уровня контракта, в котором описаны модели запросов и ответов конкретных эндпоинтов. some-endpoint.yaml - файл третьего уровня контракта, в котором развёрнуто описаны все используемые в конкретных моделях запросов и ответов поля.  При этом api.yaml, some-endpoint.yaml и components.yaml являются обычными файлами openapi спецификации. Разделение на несколько уровней обусловлено желанием снизить сложность работы с API. Так разные файлы дают возможность работать отдельно с эндпоинтами, моделями и полями. api.yaml - файл первого уровня контракта, в котором описаны эндпоинты, теги и id. Информация о версии openapi, описание спецификации и версия которую присваиваем мы. Для удобства работы с файлами рекомендуется держать version одинаковыми в  соответствующих some-endpoint.yaml и components.yaml файлах.Здесь можно написать заполнить разные поля о самой спецификации. При генерации сервера в качестве базового url контроллера будет использоваться первый из перечисленных серверов. Чтобы избежать лишних конфигураций стоит использовать конструкцию из примера и получить '/' в качестве базового пути.Для клиента первый url будет генерироваться как адрес по умолчанию. Тэги используются как часть имени генерируемого контроллера и клиента. Рекомендуется указывать camel case название класса чтобы получать привычные названия классов на выходе. Для того, чтобы метод сгенерировался в нужном контроллере необходимо указать tags и в самом методе.operationId здесь это название java методов которые будут генерироваться в сервере и клиенте. Пишем их сразу в camelCase. При описании моделей запросов и ответов мы указываем только ссылки на них. some-endpoint.yaml - файл второго уровня контракта, в котором описаны модели запросов и ответов конкретных эндпоинтов. На каждый эндпоинт создаётся отдельный файл. Описание файла. Из интересного здесь - ограничение спецификации. Она не может считаться валидной без указания хотя бы одного пути. Описываем наши объекты, показываем что в них существуют поля, и оставляем ссылки на них. components.yaml - файл третьего уровня контракта, в котором развёрнуто описаны все используемые в конкретных моделях поля. Подробно описываем наши поля, не забываем про примеры, валидацию и другие важные атрибуты Немного про генерацию со стороны OpenApi. Существуют разные генераторы, список которых можно посмотреть здесь. Из этого списка мы будем пользоваться spring генератором, описание которого можно посмотреть здесь. Хоть этот генератор и находится в категории servers, мы будем использовать его для генерации и серверной и клиентской части. Можно подсматривать в пример проекта где уже настроена генерация. Для подключения спецификации и генерации по ней мы идём в build.gradle, где подключаем плагин и добавляем следующие зависимости: Делаем поправку на актуальные версии, не забываем подключить spring-web и spring-openfeign. Далее настраиваем генерацию начиная с этой строки. Подключаем сгенерированный код в исходники. Эти строки закомментированы ввиду того что подключение к репозиторию со спецификациями в Github происходит без дополнительной авторизации. Но если вы работает с приватными ресурсами - эти строки помогут вам настроить доступ к файлам. Регистрируем задание на генерацию клиента и указываем GenerateTask из подключенного плагина. generatorName.set("spring") - указываем что мы хотим использовать генератор для spring приложения.  remoteInputSpec.set("https://raw.githubusercontent.com/SaintCheshire/specifications/main/repository/spring-boot-openapi-generation/1.0.0/api.yaml") - указываем где лежит входная точка в конкретную версию API нашего сервиса. Нужно обратить внимание что ссылка указывается на raw представление нашей спецификации.  outputDir.set("$buildDir/generated") - указываем директорию куда будут складываться сгенерированные классы (та самая которую мы включили в исходники) ignoreFileOverride.set(".openapi-generator-ignore") - ссылка на важный файлик, который поможет игнорировать сгенерированные Application классы Настройки самого генератора. library: "spring-boot" - указываем что мы хотим сгенерировать именно серверную часть Далее идёт указание списка директорий, в которых мы хотим разместить результат генерации. Указываем подробно, потому что мы можем использовать спецификацию нескольких сервисов, несколько версий, и генерировать клиента и сервер одновременно. additionalModelTypeAnnotations и generatedConstructorWithRequiredArgs - говорим что не нужно генерировать RequiredArgs конструктор, и вешаем свой набор аннотаций на модели. useTags: "true" - важный параметр, который определяет что в качестве имён классов и методов будут использоваться те самые теги При генерации клиента свойства задания указываются аналогично. Самое важное - указать library: "spring-cloud", что позволит нам генерировать уже клиента. Далее чтобы подключить серверную часть, нам необходимо создать свой контроллер, наследующий сгенерированный, и повесить аннотацию @Controller.После этого остаётся только написать логику за нашими эндпоинтами переопределив сгенерированные методы.Чтобы подключить клиентскую часть, необходимо добавить в конфигурацию нашего приложения обнаружение feign клиентов: После этого остаётся использовать сгенерированный feign как обычный spring компонент.