Учебник по Swagger UI и публикации документации
Swagger UI — это инструмент визуализации документации API, основанный на спецификации OpenAPI (ранее — спецификации Swagger). Он может преобразовывать документы спецификации API в интерактивный интерфейс документации API.
Через Swagger UI разработчики и пользователи могут:
- Просматривать подробную информацию об API
- Тестировать запросы API прямо в интерфейсе
- Просматривать примеры запросов и ответов
- Понимать функциональность и параметры различных конечных точек API
Преимущества Swagger UI
- Визуализация: Предоставляет чёткий и интуитивно понятный интерфейс документации API
- Интерактивность: Поддерживает онлайн-тестирование API без дополнительных инструментов
- Обновления в реальном времени: Документация автоматически обновляется после изменений кода
- Стандартизация: На основе спецификации OpenAPI, поддержание согласованности
- Кросс-языковая поддержка: Применимо к различным языкам программирования и фреймворкам
Интеграция Swagger UI
1. Интеграция в проект Spring Boot
Добавьте зависимости
Вpom.xmlДобавьте следующие зависимости:
Пример
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<!-- Springfox Swagger UI -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
Или используйте SpringDoc OpenAPI:
Пример
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.14</version>
</dependency>
Настройка Swagger
Пример
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.controller"))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Документация API")
.description("Подробное описание API")
.version("1.0.0")
.contact(new Contact("Команда разработчиков", "https://example.com", "[email protected]"))
.build();
}
}
Для SpringDoc OpenAPI:
Пример
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.Contact;
@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("Документация API")
.version("1.0.0")
.description("Подробное описание API")
.contact(new Contact()
.name("Команда разработчиков")
.email("[email protected]")
.url("https://example.com")));
}
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("public-apis")
.pathsToMatch("/api/**")
.build();
}
}
2. Интеграция в проект Node.js Express
Установите зависимости
npm install swagger-jsdoc swagger-ui-express --save
Настройка Swagger
Пример
const swaggerJsDoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');
const app = express();
// Конфигурация Swagger
const swaggerOptions = {
определение: {
openapi: '3.0.0',
информация: {
title: 'Документация API',
version: '1.0.0',
description: 'Подробное описание API',
contact: {
name: 'Команда разработки',
email: '[email protected]',
url: 'https://example.com'
}
},
servers: [
{
url: 'http://localhost:3000',
description: 'Сервер разработки'
}
]
},
apis: ['./routes/*.js'] // Путь к файлу маршрута API
};
const swaggerDocs = swaggerJsDoc(swaggerOptions);
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocs));
// ... другие маршруты и промежуточное ПО
app.listen(3000, () => {
console.log('Сервер запущен по адресу http://localhost:3000');
console.log('Документация API доступна по адресу http://localhost:3000/api-docs');
});
3. Использование в проекте Python FastAPI
FastAPI по умолчанию интегрирует Swagger UI:
Пример
app = FastAPI(
title="Документация API",
description="Подробное описание API",
version="1.0.0",
contact={
"name": "Команда разработки",
"email": "[email protected]",
"url": "https://example.com",
},
)
@app.get("/")
async def root():
return {"message": "Hello World"}
Swagger UI по умолчанию доступен по пути /docs. Вы можете просмотреть документацию, перейдя по адресу http://localhost:8000/docs.
Подробнее см.:Интерактивная документация API FastAPI
Написание документации API
1. Аннотации документации API в проекте Spring Boot
Пример
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
@Api(tags = "Управление пользователями")
public class UserController {
@ApiOperation(value = "Получить список пользователей", notes = "Получить всю информацию о пользователях с пагинацией")
@ApiResponses({
@ApiResponse(code = 200, message = "Успешно"),
@ApiResponse(code = 400, message = "Некорректные параметры запроса"),
@ApiResponse(code = 500, message = "Внутренняя ошибка сервера")
})
@GetMapping("/")
public Page<User> getUsers(
@ApiParam(value = "Номер страницы", required = true) @RequestParam int page,
@ApiParam(value = "Количество записей на странице", required = true) @RequestParam int size) {
// Бизнес-логика
return userService.getUsers(page, size);
}
@ApiOperation(value = "Получить одного пользователя", notes = "Получить информацию о пользователе по ID")
@GetMapping("/{id}")
public User getUser(
@ApiParam(value = "ID пользователя", required = true) @PathVariable Long id) {
// Бизнес-логика
return userService.getUser(id);
}
@ApiOperation(value = "Создать пользователя", notes = "Создать нового пользователя")
@PostMapping("/")
public User createUser(
@ApiParam(value = "Информация о пользователе", required = true) @RequestBody UserDTO userDTO) {
// Бизнес-логика
return userService.createUser(userDTO);
}
}
Для SpringDoc OpenAPI:
Пример
import io.swagger.v3.oas.annotations.media.*;
import io.swagger.v3.oas.annotations.responses.*;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
@Tag(name = "Управление пользователями", description = "API, связанные с пользователями")
public class UserController {
@Действие(
summary = "Получить список пользователей",
description = "Получить всю информацию о пользователях с пагинацией"
)
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Успешно"),
@ApiResponse(responseCode = "400", description = "Недопустимые параметры запроса"),
@ApiResponse(responseCode = "500", description = "Внутренняя ошибка сервера")
})
@GetMapping("/")
public Page<User> getUsers(
@Parameter(description = "Номер страницы", required = true) @RequestParam int page,
@Parameter(description = "Количество записей на странице", required = true) @RequestParam int size) {
// Бизнес-логика
return userService.getUsers(page, size);
}
}
2. Комментарии к документации API в проекте Node.js Express
Пример
* @swagger
* /api/users:
* get:
* summary: Получить список пользователей
* description: Получить всю информацию о пользователях с постраничной разбивкой
* tags: [Управление пользователями]
* parameters:
* - in: query
* name: page
* schema:
* type: integer
* required: true
* description: Номер страницы
* - in: query
* name: size
* schema:
* type: integer
* required: true
* description: Количество записей на странице
* responses:
* 200:
* description: Успешно
* content:
* application/json:
* schema:
* type: object
* properties:
* data:
* type: array
* items:
* $ref: '#/components/schemas/User'
* total:
* type: integer
* 400:
* description: Недопустимые параметры запроса
* 500:
* description: Внутренняя ошибка сервера
*/
router.get('/users', (req, res) => {
// Бизнес-логика
});
/**
* @swagger
* components:
* schemas:
* User:
* type: object
* required:
* - name
* properties:
* id:
* type: integer
* description: ID пользователя
* name:
* type: string
* description: Имя пользователя
* email:
* type: string
* format: email
* description: Электронная почта пользователя
*/
3. Документация API в проекте Python FastAPI
Пример
from pydantic import BaseModel
from typing import List, Optional
app = FastAPI(title="API управления пользователями")
class User(BaseModel):
id: int
name: str
email: str
class Config:
schema_extra = {
"example": {
"id": 1,
"name": "Чжан Сань",
"email": "[email protected]"
}
}
@app.get(
"/api/users/",
summary="Получить список пользователей",
description="Получить всю информацию о пользователях с пагинацией",
response_model=List[User],
tags=["Управление пользователями"]
)
async def get_users(
page: int = Query(..., description="Номер страницы", ge=1),
size: int = Query(..., description="Количество записей на странице", ge=1, le=100)
):
# Бизнес-логика
return [
{"id": 1, "name": "Чжан Сан", "email": "[email protected]"},
{"id": 2, "name": "Ли Сы", "email": "[email protected]"}
]
@app.get(
"/api/users/{user_id}",
summary="Получить одного пользователя",
description="Получить информацию о пользователе по ID",
response_model=User,
tags=["Управление пользователями"]
)
async def get_user(
user_id: int = Путь(..., описание="ID пользователя", ge=1)
):
# Бизнес-логика
return {"id": user_id, "name": "Чжан Сань", "email": "[email protected]"}
Настройка Swagger UI
1. Пользовательская конфигурация Spring Boot
Пример
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.controller"))
.paths(PathSelectors.regex("/api/.*"))
.build()
.apiInfo(apiInfo())
.useDefaultResponseMessages(false) // Отключить стандартные сообщения ответов
.globalResponseMessage(RequestMethod.GET, globalResponses()) // Пользовательские глобальные сообщения ответов
.securitySchemes(Arrays.asList(apiKey())) // Настроить аутентификацию безопасности
.securityContexts(Arrays.asList(securityContext())); // Настроить контекст безопасности
}
private List<ResponseMessage> globalResponses() {
return Arrays.asList(
new ResponseMessageBuilder().code(200).message("Успех").build(),
new ResponseMessageBuilder().code(400).message("Недопустимые параметры запроса").build(),
new ResponseMessageBuilder().code(401).message("Неавторизован").build(),
new ResponseMessageBuilder().code(403).message("Доступ запрещён").build(),
new ResponseMessageBuilder().code(500).message("Внутренняя ошибка сервера").build()
);
}
private ApiKey apiKey() {
return new ApiKey("JWT", "Authorization", "header");
}
private SecurityContext securityContext() {
return SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("/api/.*"))
.build();
}
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return Arrays.asList(new SecurityReference("JWT", authorizationScopes));
}
2. Пользовательская конфигурация Express
Пример
customCss: '.swagger-ui .topbar { display: none }', // Пользовательский CSS
customSiteTitle: "Центр документации API", // Заголовок страницы
customfavIcon: "/favicon.png", // Пользовательская иконка
swaggerOptions: {
persistAuthorization: true, // Сохранять информацию об авторизации
docExpansion: 'none', // Свернуть все интерфейсы по умолчанию
tagsSorter: 'alpha', // Сортировать теги по алфавиту
operationsSorter: 'alpha', // Сортировать операции по алфавиту
defaultModelsExpandDepth: -1, // Скрыть модели
filter: true, // Включить фильтрацию
}
};
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocs, options));
3. Пользовательская конфигурация FastAPI
Пример
from fastapi.openapi.docs import get_swagger_ui_html
from fastapi.staticfiles import StaticFiles
app = FastAPI(
title="Документация по интерфейсу API",
docs_url=None, # Отключить стандартный Swagger UI
)
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
return get_swagger_ui_html(
openapi_url=app.openapi_url,
title=app.title + " - Документация API",
oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
swagger_js_url="/static/swagger-ui-bundle.js",
swagger_css_url="/static/swagger-ui.css",
swagger_favicon_url="/static/favicon.png",
swagger_ui_parameters={
"docExpansion": "none",
"defaultModelsExpandDepth": -1,
"filter": True,
}
)
Публикация документации
1. Внутренняя публикация
Для использования внутри команды вы можете напрямую открыть Swagger UI в приложении:
- Spring Boot:
http://your-app-host:port/swagger-ui/index.html - Express:
http://your-app-host:port/api-docs - FastAPI:
http://your-app-host:port/docs
2. Генерация статической документации
Используйте Swagger Codegen для создания статической документации
# 安装 Swagger Codegen CLI wget https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.35/swagger-codegen-cli-3.0.35.jar -O swagger-codegen-cli.jar # 生成静态 HTML 文档 java -jar swagger-codegen-cli.jar generate -i http://your-app-host:port/v3/api-docs -l html2 -o ./api-docs
Используйте Redoc для создания статической документации
# 安装 redoc-cli npm install -g redoc-cli # 生成静态 HTML 文档 redoc-cli bundle http://your-app-host:port/v3/api-docs -o ./api-docs/index.html
3. Интеграция в CI/CD-конвейер
Добавьте этапы генерации и публикации документации в CI/CD-конвейер:
Пример Jenkins Pipeline
Пример
agent any
stages {
// ... другие этапы сборки и тестирования
stage('Генерация документации API') {
steps {
sh 'java -jar swagger-codegen-cli.jar generate -i http://your-app-host:port/v3/api-docs -l html2 -o ./api-docs'
}
}
stage('Публикация документации') {
steps {
// Публикация на статическом файловом сервере Nginx
sh 'rsync -avz --delete ./api-docs/ user@doc-server:/var/www/api-docs/'
// Или опубликовать в объектном хранилище (например, AWS S3)
sh 'aws s3 sync ./api-docs/ s3://your-bucket/api-docs/ --delete'
}
}
}
}
Пример рабочего процесса GitHub Actions
Пример
на:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Настроить JDK
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '11'
- name: Сборка приложения
run: ./mvnw clean package
- name: Запуск приложения
run: |
java -jar target/your-app.jar &
sleep 30# Ожидание запуска приложения
- name: Генерация документации API
run: |
wget -q https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.35/swagger-codegen-cli-3.0.35.jar -O swagger-codegen-cli.jar
java -jar swagger-codegen-cli.jar generate -i http://localhost:8080/v3/api-docs -l html2 -o ./api-docs
- name: Развертывание на GitHub Pages
uses: JamesIves/github-pages-deploy-action@4.1.5
with:
branch: gh-pages
folder: api-docs
4. Использование платформы управления документацией API
Помимо самостоятельного развертывания, вы также можете использовать профессиональные платформы управления документацией API:
- Swagger Hub: Предоставляет услуги хостинга для проектирования API и документации
- Postman: Позволяет тестировать API, а также публиковать документацию API
- ReadMe.io: Предоставляет комплексное управление документацией API и портал для разработчиков
- Stoplight: Предоставляет инструменты для проектирования, документирования и управления API
5. Развертывание Swagger UI с помощью Docker
Пример
# Установка переменных окружения
ENV SWAGGER_JSON=/swagger/openapi.json
ENV BASE_URL=/api-docs
# Копирование файла спецификации OpenAPI
COPY openapi.json /swagger/
# Открыть порт
EXPOSE 8080
# Запуск Swagger UI
CMD ["sh", "/usr/share/nginx/docker-run.sh"]
Сборка и запуск:
docker build -t my-swagger-ui . docker run -p 8080:8080 my-swagger-ui
Доступ: http://localhost:8080/api-docs
Лучшие практики
1. Стандарты документации
- Будьте кратки и понятны: Описания должны быть краткими и по существу
- Управление группами: Используйте теги для логической группировки API
- Приводите примеры: Приводите примеры запросов и ответов
- Стандартизируйте обработку ошибок: Стандартизируйте формат ответов об ошибках и коды состояния
- Управление версиями: Четко указывайте информацию о версии API в документации
2. Конфигурация безопасности
- Обработка конфиденциальной информации: Не раскрывайте конфиденциальную информацию в документации
- Конфигурация производственной среды: При необходимости отключите или ограничьте доступ к документации в производственной среде
- Механизм аутентификации: Настройте аутентификацию для доступа к документации
Пример
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.enable(!environment.acceptsProfiles(Profiles.of("prod")))
// ... другие конфигурации
}
3. Автоматизированное тестирование
Объедините документацию и тесты, чтобы содержимое документации оставалось согласованным с фактическим поведением API:
Пример
@Test
public void validateSwaggerDocumentation() {
// Получить Swagger JSON
String swaggerJson = given()
.когда()
.get("/v3/api-docs")
.затем()
.statusCode(200)
.extract().asString();
// Проверить документацию Swagger
OpenAPI openAPI = new OpenAPIParser().readContents(swaggerJson, null, null).getOpenAPI();
assertNotNull(openAPI);
// Проверить, существует ли конкретный эндпоинт в документации
assertNotNull(openAPI.getPaths().get("/api/users"));
}
Устранение распространённых проблем
1. Swagger UI не отображается или ошибки при загрузке
- Проверьте версии зависимостей: Убедитесь, что версии зависимостей совместимы
- Проверьте классы конфигурации: Убедитесь, что классы конфигурации зарегистрированы правильно
- Проверьте сопоставления путей: Убедитесь, что сопоставления путей верны
- Проверьте настройки cross-origin: Если доступ осуществляется из другого источника, убедитесь, что конфигурация CORS верна
2. Неполная информация об API
- Проверьте аннотации: убедитесь, что все необходимые аннотации добавлены
- Проверьте пути сканирования пакетов: убедитесь, что пути сканирования включают все контроллеры
- Проверьте классы моделей: убедитесь, что классы моделей имеют корректные описания
3. Проблемы безопасности в производственной среде
Настройте производственную среду, чтобы отключить или защитить документацию:
# application-prod.properties springdoc.swagger-ui.enabled=false springdoc.api-docs.enabled=false
Или защитите с помощью базовой аутентификации:
Пример
@Profile("prod")
public class SwaggerSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.antMatchers("/swagger-ui/**", "/v3/api-docs/**")
.и()
.authorizeRequests()
.anyRequest().hasRole("ADMIN")
.и()
.httpBasic();
}
}
Итог
Swagger UI — мощный инструмент документирования API. При правильной настройке и использовании он может значительно повысить удобство использования API и эффективность разработки. В этом руководстве рассматриваются основные концепции Swagger UI, методы интеграции, написание документации, пользовательская настройка, публикация документации и лучшие практики — в надежде, что это будет полезно для вашей работы с документацией API.
Запомните следующие ключевые моменты:
- Выберите метод интеграции Swagger, подходящий для технологического стека вашего проекта
- Тщательно проектируйте и пишите аннотации или комментарии для документации API
- Настраивайте интерфейс Swagger UI по мере необходимости
- Выберите подходящий способ публикации документации
- Следуйте лучшим практикам, чтобы обеспечить точность и безопасность документации
Правильно используя Swagger UI, вы можете предоставить профессиональную, интерактивную документацию для вашего API, что сделает ваш API более понятным и удобным в использовании.
Другие расширения