1. 概要

Swaggerを使用して検証を生成する場合は、通常、基本仕様を使用します。 ただし、Springカスタム検証アノテーションを追加する必要がある場合があります。

このチュートリアルでは、制約検証ツールではなく、OpenAPIサーバージェネレーターに焦点を当てながら、これらの検証を使用してモデルとRESTAPIを生成する方法を説明します。

2. 設定

セットアップでは、前のBaeldungチュートリアルを使用して、OpenAPI3.0.0定義からサーバーを生成します。 次に、必要なすべての依存関係に加えて、いくつかのカスタム検証アノテーションを追加します。

3. PetStoreAPIOpenAPI定義

PetStore API OpenAPI定義があり、RESTAPIと説明されているモデルPetの両方にカスタム検証を追加する必要があるとします。

3.1. APIモデルのカスタム検証

ペットを作成するには、Swaggerにカスタム検証アノテーションを使用させて、ペットの名前が大文字になっているかどうかをテストする必要があります。 したがって、このチュートリアルでは、これをCapitalizedと呼びます。

したがって、以下の例のx-constraints仕様を順守してください。 既知のアノテーションとは別のタイプのアノテーションを生成する必要があることを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. RESTAPIエンドポイントのカスタム検証

上記のように、同じ方法ですべてのペットを名前で検索するエンドポイントについて説明します。 目的を示すために、システムで大文字と小文字が区別されると仮定して、name入力パラメーターに同じx-constraints検証を再度追加します。

/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
}

デモの目的で必須のメソッドを作成したことに注意してください。これについては後で説明します。

次に、上記の@Constraintアノテーションで参照されているCapitalizedValidatorを追加します。

public class CapitalizedValidator implements ConstraintValidator<Capitalized, String> {

    @Override
    public boolean isValid(String nameField, ConstraintValidatorContext context) {
        // validation code here
    }
}

5. 検証アノテーションの生成

5.1. Mustacheテンプレートディレクトリの指定

@Capitalized 検証アノテーションを使用してモデルを生成するには、モデル内で生成するようにSwaggerに指示する特定の口ひげテンプレートが必要です。

したがって、OpenAPIジェネレータプラグインでは、 [..] タグの場合、テンプレートディレクトリを追加する必要があります。

<plugin>  
  //... 
  <executions>
    <execution>
      <configuration
        //...
        <templateDirectory>
          ${project.basedir}/src/main/resources/openapi/templates
        </templateDirectory>
        //...
      </configuration>
    </execution>
  </executions>        
  //...
</plugin> 

5.2. MustacheBean検証構成の追加

この章では、検証仕様を生成するようにMustacheテンプレートを構成します。 詳細を追加するには、 beanValidationCore.mustache model.mustache 、およびapi.muctacheファイルを変更してコードを正常に生成します。

まず、swagger-codegenモジュールのbeanValidationCore.mustacheを、ベンダー拡張仕様を追加して変更する必要があります。

{{{ vendorExtensions.x-constraints }}}

次に、 @Capitalized(required =“ true”)のような内部プロパティを持つアノテーションがある場合、beanValidationCore.mustacheファイルの2行目の特定のパターンは指定する:

{{#required}}@Capitalized(required="{{{pattern}}}") {{/required}}

第三に、必要なインポートを含むようにmodel.mustache仕様を変更する必要があります。 たとえば、インポートします @Capitalized 注釈と大文字インポートは、 パッケージのタグ model.mustache:

{{#imports}}import {{import}}; {{/imports}} import 
com.baeldung.openapi.petstore.validator.CapitalizedValidator; 
import com.baeldung.openapi.petstore.validator.Capitalized;

最後に、API内でアノテーションを生成するには、@Capitalizedアノテーションのインポートをapi.mustacheファイルに追加する必要があります。

{{#imports}}import {{import}}; {{/imports}} import 
com.baeldung.openapi.petstore.validator.Capitalized;

さらに、api.mustachecookieParams.mustacheファイルに依存します。 したがって、 openapi /templatesディレクトリに追加する必要があります。

6. ソースを生成する

最後に、生成されたコードを使用できます。 少なくとも、 mvngenerate-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() { return name; } // default getters and setter }

また、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 400BadRequestステータスを返します。

7.1. Petモデル検証のテスト

このPetモデルには、小文字のnameがあります。 したがって、400BadRequestがアプリによって返される必要があります。

curl -X 'POST' \
  'http://localhost:8080/pet' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "id": 1,
  "name": "rockie"
}'

7.2. Find PetAPIのテスト

上記と同じように、 name は小文字であるため、アプリケーションは400BadRequestを返す必要があります。

curl -I http://localhost:8080/pets/name="rockie"

8. 結論

このチュートリアルでは、REST APIサーバーの実装中に、Springを使用してカスタム制約バリデーターを生成できるようにする方法を説明しました。

いつものように、コードはGitHubにあります。