1. Обзор
Когда мы хотим сгенерировать проверки с помощью Swagger, мы обычно используем базовые спецификации . Однако нам может понадобиться добавить пользовательские аннотации проверки Spring .
В этом учебном пособии рассказывается, как создавать модели и REST API с использованием этих проверок, уделяя особое внимание генератору сервера OpenAPI, а не валидаторам ограничений.
2. Настройка
Для настройки мы будем использовать предыдущее руководство ForEach для создания сервера из определения OpenAPI 3.0.0 . Далее мы собираемся добавить несколько пользовательских аннотаций проверки вместе со всеми необходимыми зависимостями.
3. Определение OpenAPI API PetStore
Предположим, у нас есть определение OpenAPI PetStore API, и нам нужно добавить пользовательские проверки как для REST API, так и для описанной модели Pet
.
3.1. Пользовательские проверки для модели API
Чтобы создать питомцев, нам нужно заставить Swagger использовать нашу пользовательскую аннотацию проверки, чтобы проверить, написано ли имя питомца с большой буквы. В результате для этого урока мы просто назовем его Capitalized
.
Таким образом, обратите внимание на спецификацию x-ограничений в приведенном ниже примере.
Достаточно сообщить Swagger, что нам нужно сгенерировать аннотацию другого типа, чем уже известные:
openapi: 3.0.1
info:
version: "1.0"
title: PetStore
paths:
/pets:
post:
#.. post described here
components:
schemas:
Pet:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
x-constraints: "Capitalized(required = true)"
tag:
type: string
3.2. Пользовательские проверки для конечной точки REST API
Как и выше, мы опишем конечную точку для поиска всех домашних животных по имени таким же образом. Чтобы продемонстрировать нашу цель, давайте предположим, что наша система чувствительна к регистру, поэтому мы снова добавим ту же проверку x-ограничений
для входного параметра имени :
/pets:
# post defined here
get:
tags:
- pet
summary: Finds Pets by name
description: 'Find pets by name'
operationId: findPetsByTags
parameters:
- <em>name: name</em>
in: query
schema:
type: string
description: Tags to filter by
required: true
x-constraints: "Capitalized(required = true)"
responses:
'200':
description: default response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
'400':
description: Invalid tag value
4. Создание аннотации с заглавной буквы
Чтобы применить пользовательскую проверку, нам нужно создать аннотацию, обеспечивающую функциональность.
Во-первых, мы делаем интерфейс аннотации — @Capitalized
:
@Documented
@Constraint(validatedBy = {Capitalized.class})
@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Capitalized{
String message() default "Name should be capitalized.";
boolean required() default true;
// default annotation methods
}
Обратите внимание, что мы сделали необходимый
метод для демонстрационных целей — мы объясним это позже.
Затем мы добавляем CapitalizedValidator
, упомянутый в приведенной выше аннотации @Constraint
:
public class CapitalizedValidator implements ConstraintValidator<Capitalized, String> {
@Override
public boolean isValid(String nameField, ConstraintValidatorContext context) {
// validation code here
}
}
5. Создание аннотаций проверки
5.1. Указание каталога шаблонов усов
Чтобы создавать модели с аннотацией проверки @Capitalized
, нам нужны определенные шаблоны усов, сообщающие Swagger о создании их в модели.
Таким образом, в плагине генератора OpenAPI внутри тегов <configuration>[..]</configuration
нам нужно добавить каталог шаблонов:
<plugin>
//...
<executions>
<execution>
<configuration
//...
<templateDirectory>
${project.basedir}/src/main/resources/openapi/templates
</templateDirectory>
//...
</configuration>
</execution>
</executions>
//...
</plugin>
5.2. Добавление конфигураций проверки Mustache Bean
В этой главе мы настроим шаблоны Mustache для создания спецификации проверки. Чтобы добавить больше деталей, мы изменим файлы beanValidationCore.mustache
, model.mustache
и api.muctache
для успешного создания кода.
Во-первых, beanValidationCore.mustache
из модуля swagger -
codegen необходимо изменить, добавив спецификацию расширения поставщика:
{{{ vendorExtensions.x-constraints }}}
Во-вторых, если у нас есть аннотация с внутренним свойством, например @Capitalized(required = «true»)
, то необходимо указать конкретный шаблон во второй строке файла beanValidationCore.mustache
:
{{#required}}@Capitalized(required="{{{pattern}}}") {{/required}}
В-третьих, нам нужно изменить спецификацию model.mustache
, чтобы она содержала необходимые импорты. Например, мы импортируем аннотацию @Capitalized и
заглавные буквы
.
Импорт должен быть вставлен после тега package в
model.mustache
:
{{#imports}}import {{import}}; {{/imports}} import
com.foreach.openapi.petstore.validator.CapitalizedValidator;
import com.foreach.openapi.petstore.validator.Capitalized;
Наконец, чтобы генерировать аннотации внутри API, нам нужно добавить импорт для аннотаций @Capitalized в файл
api.mustache
.
{{#imports}}import {{import}}; {{/imports}} import
com.foreach.openapi.petstore.validator.Capitalized;
Кроме того, api.mustache
зависит от файла cookieParams.mustache
. Таким образом, нам нужно добавить его в директорию openapi/templates
.
6. Генерация исходников
Чтобы закончить, мы можем использовать сгенерированный код. Нам нужно запустить, как минимум, mvn generate-sources
. Это сгенерирует модель:
public class Pet {
@JsonProperty("id")
private Long id = null;
@JsonProperty("name")
private String name = null;
// other parameters
@Schema(required = true, description = "")
@<code class="language-java">Capitalized
public String getName() {возвратное имя; } // геттеры и сеттеры по умолчанию }
И он также сгенерирует API:
default ResponseEntity<List<Pet>> findPetsByTags(
@Capitalized(required = true)
@ApiParam(value = "Tags to filter by")
@Valid @RequestParam(value = "name", required = false) String name) {
// default generated code here
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
}
7. Тестирование с помощью curl
После запуска приложения мы запустим несколько команд curl
, чтобы протестировать его.
Кроме того, обратите внимание, что нарушения ограничений вызывают исключение ConstraintViolationException.
Исключение необходимо соответствующим образом обработать с помощью @ControllerAdvice
, чтобы вернуть статус 400 Bad Request.
7.1. Тестирование проверки модели домашних животных
Эта модель питомца
имеет имя
в нижнем регистре . Таким образом, приложение должно вернуть 400 Bad Request:
curl -X 'POST' \
'http://localhost:8080/pet' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"id": 1,
"name": "rockie"
}'
7.2. Тестирование API поиска домашних животных
Так же, как и выше, поскольку имя
написано в нижнем регистре, приложение также должно вернуть 400 Bad Request:
curl -I http://localhost:8080/pets/name="rockie"
8. Заключение
В этом руководстве мы увидели, как включить создание пользовательских валидаторов ограничений с помощью Spring при реализации сервера REST API.
Как всегда, код можно найти на GitHub .