Перейти к основному содержимому

Пользовательская проверка с помощью Swagger Codegen

· 5 мин. чтения

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 .