Swagger (OpenAPI 3.0)

от автора

Всем привет!!! Это мой первый пост на Хабре и я хочу поделиться с вами своим опытом в исследование нового для себя фреймворка.

Мне предоставился момент выбрать тему и подготовить презентацию для своей команды. Вдохновившись спикером Евгений Маренков, я решил выбрать данную тему. В процессе подготовки, я облазил много статей и репозиториев что бы компактно и эффективно донести нужную информацию.

Сейчас хочу поделиться ею в надежде, что кому-то она поможет в изучение Swagger (OpenApi 3.0)

Введение

Я на 99% уверен у многих из вас были проблемы с поиском документации для нужного вам контроллера. Многие если и находили ее быстро, но в конечном итоге оказывалось что она работает не так как описано в документации, либо вообще его уже нет.
Сегодня я вам докажу, что есть способы поддерживать документацию в актуальном виде и в этом мне будет помогать Open Source framework от компании SmartBear под названием Swagger, а с 2016 года он получил новое обновление и стал называться OpenAPI Specification.

Swagger — это фреймворк для спецификации RESTful API. Его прелесть заключается в том, что он дает возможность не только интерактивно просматривать спецификацию, но и отправлять запросы – так называемый Swagger UI.

Также возможно сгенерировать непосредственно клиента или сервер по спецификации API Swagger, для этого понадобиться Swagger Codegen.

Основные подходы

Swagger имеет два подхода к написанию документации:

  • Документация пишется на основании вашего кода.

    • Данный подход позиционируется как «очень просто». Нам достаточно добавить несколько зависимостей в проект, добавить конфигурацию и уже мы будем иметь нужную документацию, хоть и не настолько описанной какою мы хотели.

    • Код проекта становиться не очень читабельным от обилия аннотаций и описания в них.

    • Вся документация будет вписана в нашем коде (все контроллеры и модели превращаются в некий Java Swagger Code)

    • Подход не советуют использовать, если есть возможности, но его очень просто интегрировать.

  • Документация пишется отдельно от кода.

    • Данный подход требует знать синтаксис Swagger Specification.

    • Документация пишется либо в JAML/JSON файле, либо в редакторе Swagger Editor.

Swagger Tools

Swagger или OpenAPI framework состоит из 4 основных компонентов:

  1. Swagger Core — позволяет генерировать документацию на основе существующего кода основываясь на Java Annotation.

  2. Swagger Codegen — позволит генерировать клиентов для существующей документации.

  3. Swagger UI — красивый интерфейс, который представляет документацию. Дает возможность просмотреть какие типы запросов есть, описание моделей и их типов данных.

  4. Swagger Editor — Позволяет писать документацию в YAML или JSON формата.

Теперь давайте поговорим о каждом компоненте отдельно.

Swagger Core

Swagger Code — это Java-реализация спецификации OpenAPI

Для того что бы использовать Swagger Core во все орудие, требуется:

  • Java 8 или больше

  • Apache Maven 3.0.3 или больше

  • Jackson 2.4.5 или больше

Что бы внедрить его в проект, достаточно добавить две зависимости:

<dependency>     <groupId>io.swagger.core.v3</groupId>     <artifactId>swagger-annotations</artifactId>     <version>2.1.6</version> </dependency> <dependency>     <groupId>org.springdoc</groupId>     <artifactId>springdoc-openapi-ui</artifactId>     <version>1.5.2</version> </dependency>

Также можно настроить maven плагин, что бы наша документация при сборке проект генерировалсь в YAML

<plugin>  <groupId>org.springdoc</groupId>  <artifactId>springdoc-openapi-maven-plugin</artifactId>  <version>0.3</version>  <executions>    <execution>    <phase>integration-test</phase>    <goals>      <goal>generate</goal>    </goals>    </execution>  </executions>  <configuration>    <apiDocsUrl>http://localhost:8080/v3/api-docs</apiDocsUrl>    <outputFileName>openapi.yaml</outputFileName>    <outputDir>${project.build.directory}</outputDir>  </configuration> </plugin>

Дальше нам необходимо добавить конфиг в проект.

Для конфигурации Swagger необходимо добавить два бина. Где нам нужно будет описать название приложения, версию нашего API, так же можно добавить контакт разработчик который отвечает за данные API

    @Bean     public GroupedOpenApi publicUserApi() {         return GroupedOpenApi.builder()                              .group("Users")                              .pathsToMatch("/users/**")                              .build();     }      @Bean     public OpenAPI customOpenApi(@Value("${application-description}")String appDescription,                                  @Value("${application-version}")String appVersion) {         return new OpenAPI().info(new Info().title("Application API")                                             .version(appVersion)                                             .description(appDescription)                                             .license(new License().name("Apache 2.0")                                                                   .url("http://springdoc.org"))                                             .contact(new Contact().name("username")                                                                   .email("test@gmail.com")))                             .servers(List.of(new Server().url("http://localhost:8080")                                                          .description("Dev service"),                                              new Server().url("http://localhost:8082")                                                          .description("Beta service")));     }

После добавление нужных нам зависимостей, у нас появятся новые аннотация с помощью которых можно документировать наш код.

Вот некоторые из них:

  • @Operation — Описывает операцию или обычно метод HTTP для определенного пути.

  • @Parameter — Представляет один параметр в операции OpenAPI.

  • @RequestBody — Представляет тело запроса в операции

  • @ApiResponse — Представляет ответ в операции

  • @Tag — Представляет теги для операции или определения OpenAPI.

  • @Server — Представляет серверы для операции или для определения OpenAPI.

  • @Callback — Описывает набор запросов

  • @Link — Представляет возможную ссылку времени разработки для ответа.

  • @Schema — Позволяет определять входные и выходные данные.

  • @ArraySchema — Позволяет определять входные и выходные данные для типов массивов.

  • @Content — Предоставляет схему и примеры для определенного типа мультимедиа.

  • @Hidden — Скрывает ресурс, операцию или свойство

Примеры использования:

@Tag(name = "User", description = "The User API") @RestController public class UserController {}
    @Operation(summary = "Gets all users", tags = "user")     @ApiResponses(value = {             @ApiResponse(                     responseCode = "200",                     description = "Found the users",                     content = {                             @Content(                                     mediaType = "application/json",                                     array = @ArraySchema(schema = @Schema(implementation = UserApi.class)))                     })     })     @GetMapping("/users")     public List<UserApi> getUsers()

Swagger Codegen

Swagger Codegen — это проект, который позволяет автоматически создавать клиентские библиотеки API (создание SDK), заглушки сервера и документацию с учетом спецификации OpenAPI.

В настоящее время поддерживаются следующие языки / фреймворки:

  • API clients:

    • Java (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java, Rest-assured)

    • Kotlin

    • Scala (akka, http4s, swagger-async-httpclient)

    • Groovy

    • Node.js (ES5, ES6, AngularJS with Google Closure Compiler annotations)

    • Haskell (http-client, Servant)

    • C# (.net 2.0, 3.5 or later)

    • C++ (cpprest, Qt5, Tizen)

    • Bash

  • Server stub:

    • Java (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, RestEasy, Play Framework, PKMST)

    • Kotlin

    • C# (ASP.NET Core, NancyFx)

    • C++ (Pistache, Restbed)

    • Haskell (Servant)

    • PHP (Lumen, Slim, Silex, Symfony, Zend Expressive)

    • Python (Flask)

    • NodeJS

    • Ruby (Sinatra, Rails5)

    • Rust (rust-server)

    • Scala (Finch, Lagom, Scalatra)

  • API documentation generators:

    • HTML

    • Confluence Wiki

  • Other:

    • JMeter

Что бы внедрить его в проект, достаточно добавить зависимость, если используете Swagger:

<dependency>     <groupId>io.swagger</groupId>     <artifactId>swagger-codegen-maven-plugin</artifactId>     <version>2.4.18</version> </dependency>

и если используете OpenApi 3.0, то:

<dependency>     <groupId>io.swagger.codegen.v3</groupId>     <artifactId>swagger-codegen-maven-plugin</artifactId>     <version>3.0.24</version> </dependency>

Можно настроить maven плагин, и уже на процессе сборки мы можем сгенерировать нужный для нас клиент либо мок сервиса.

      <plugin>         <groupId>org.openapitools</groupId>         <artifactId>openapi-generator-maven-plugin</artifactId>         <version>3.3.4</version>         <executions>           <execution>             <phase>compile</phase>             <goals>               <goal>generate</goal>             </goals>             <configuration>               <generatorName>spring</generatorName>               <inputSpec>${project.basedir}/src/main/resources/api.yaml</inputSpec>               <output>${project.build.directory}/generated-sources</output>               <apiPackage>com.api</apiPackage>               <modelPackage>com.model</modelPackage>               <supportingFilesToGenerate>                 ApiUtil.java               </supportingFilesToGenerate>               <configOptions>                 <groupId>${project.groupId}</groupId>                 <artifactId>${project.artifactId}</artifactId>                 <artifactVersion>${project.version}</artifactVersion>                 <delegatePattern>true</delegatePattern>                 <sourceFolder>swagger</sourceFolder>                 <library>spring-mvc</library>                 <interfaceOnly>true</interfaceOnly>                 <useBeanValidation>true</useBeanValidation>                 <dateLibrary>java8</dateLibrary>                 <java8>true</java8>               </configOptions>               <ignoreFileOverride>${project.basedir}/.openapi-generator-ignore</ignoreFileOverride>             </configuration>           </execution>         </executions>       </plugin>

Также все это можно выполнить с помощью командной строки.

Запустив джарник codegen и задав команду help можно увидеть команды, которые предоставляет нам Swagger Codegen:

  • config-help — Справка по настройке для выбранного языка

  • generate — Сгенерировать код с указанным генератором

  • help — Отображение справочной информации об openapi-generator

  • list — Перечисляет доступные генераторы

  • meta — Генератор для создания нового набора шаблонов и конфигурации для Codegen. Вывод будет основан на указанном вами языке и будет включать шаблоны по умолчанию.

  • validate — Проверить спецификацию

  • version — Показать информацию о версии, используемую в инструментах

Для нас самые нужные команды это validate, которая быстро проверять на валидность спецификации и generate, с помощью которой мы можем сгенерировать Client на языке Java

  • java -jar openapi-generator-cli-4.3.1.jar validate -i openapi.yaml

  •  java -jar openapi-generator-cli-4.3.1.jar generate -i openapi.yaml -g java —library jersey2 -o client-gener-new

Swagger UI

Swagger UI — позволяет визуализировать ресурсы API и взаимодействовать с ними без какой-либо логики реализации. Он автоматически генерируется из вашей спецификации OpenAPI (ранее известной как Swagger), а визуальная документация упрощает внутреннюю реализацию и использование на стороне клиента.

Вот пример Swagger UI который визуализирует документацию для моего pet-project:

Нажавши на кнопку «Try it out», мы можем выполнить запрос за сервер и получить ответ от него:

Swagger Editor

Swagger Editor — позволяет редактировать спецификации Swagger API в YAML внутри вашего браузера и просматривать документацию в режиме реального времени. Затем можно сгенерировать допустимые описания Swagger JSON и использовать их с полным набором инструментов Swagger (генерация кода, документация и т. Д.).

На верхнем уровне в спецификации OpenAPI 3.0 существует восемь объектов. Внутри этих верхнеуровневых объектов есть много вложенных объектов, но на верхнем уровне есть только следующие объекты:

  1. openapi

  2. info

  3. servers

  4. paths

  5. components

  6. security

  7. tags

  8. externalDocs

Для работы над документацией со спецификацией используется онлайн-редактор Swagger Редактор Swagger имеет разделенное представление: слева пишем код спецификации, а справа видим полнофункциональный дисплей Swagger UI. Можно даже отправлять запросы из интерфейса Swagger в этом редакторе.

Редактор Swagger проверит контент в режиме реального времени, и укажет ошибки валидации, во время кодирования документа спецификации. Не стоит беспокоиться об ошибках, если отсутствуют X-метки в коде, над которым идет работа.

Первым и важным свойством для документации это openapi. В объекте указывается версия спецификации OpenAPI. Для Swagger спецификации это свойство будет swagger:

 openapi: "3.0.2"

Объект info содержит основную информацию о вашем API,включая заголовок, описание, версию, ссылку на лицензию, ссылку на обслуживания и контактную информацию. Многие из этих свойство являются не обязательными.

info:   title: "OpenWeatherMap API"   description: "Get the current weather, daily forecast for 16 days, and a three-hour-interval forecast for 5 days for your city."   version: "2.5"   termsOfService: "https://openweathermap.org/terms"   contact:   	name: "OpenWeatherMap API"     url: "https://openweathermap.org/api"     email: "some_email@gmail.com"   license:     name: "CC Attribution-ShareAlike 4.0 (CC BY-SA 4.0)"     url: "https://openweathermap.org/price"

Объект servers указывает базовый путь, используемый в ваших запросах API. Базовый путь — это часть URL, которая находится перед конечной точкой. Объект servers обладает гибкой настройкой. Можно указать несколько URL-адресов:

servers:   - url: https://api.openweathermap.org/data/2.5/         description: Production server   - url: http://beta.api.openweathermap.org/data/2.5/         description: Beta server   - url: http://some-other.api.openweathermap.org/data/2.5/         description: Some other server

paths — Это та же “конечная точка” в соответствии с терминологии спецификации OpenAPI. Каждый объект path содержит объект operations — это методы GET, POST, PUT, DELETE:

paths:   /weather:      get:

Объект components уникален среди других объектов в спецификации OpenAPI. В components хранятся переиспользуемые определения, которые могут появляться в нескольких местах в документе спецификации. В нашем сценарии документации API мы будем хранить детали для объектов parameters и responses в объекте components

Conclusions

  • Документация стала более понятней для бизнес юзера так и для техническим юзерам (Swagger UI, Open Specifiation)

  • Может генерировать код для Java, PHP, .NET, JavaScrypt (Swager Editor, Swagger Codegen)

  • Можно проверять насколько совместимы изменения. Можно настраивать это в дженкинсе

  • Нет ни какой лишней документации к коде, код отдельно, документация отдельно

ссылка на оригинал статьи https://habr.com/ru/post/541592/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *