Spring Boot API連携

Spring BootのRest APIサービスで利用している、Swaggerによるドキュメント定義を編集してみた

Spring BootのRest APIサービスのドキュメントを定義したり、API実行を行ったりできるためのライブラリにSwaggerがあるが、Swaggerのドキュメント定義を編集することもできる。

今回は、STS(Spring Tool Suite)を利用したSpring Bootアプリケーション上に記載してある、Swaggerによるドキュメント定義を編集してみたので、そのサンプルプログラムを共有する。

前提条件

下記記事の実装が完了していること。

Spring BootのRest APIサービスにSwaggerによるドキュメント定義を追加してみたSpring BootのRest APIサービスのドキュメントを定義したり、API実行を行ったりできるためのライブラリに、Swagger...

作成したサンプルプログラムの内容

作成したサンプルプログラムの構成は以下の通り。
サンプルプログラムの構成
なお、上記の赤枠は、前提条件のプログラムから変更したプログラムである。

コントローラクラスの内容は以下の通りで、@ApiアノテーションでAPI全体の定義を、@ApiOperationアノテーションで各API操作の定義を、@ApiResponsesアノテーション・@ApiResponseアノテーションでAPIレスポンスの定義を行っている。

package com.example.demo;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;

import java.util.List;
import java.util.Optional;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;

/**
 * Rest API定義クラス
 */
@Api(tags="OperateUserData")
@RestController
public class DemoRestController {

    /** ユーザーデータテーブル(user_data)アクセス用リポジトリ */
    @Autowired
    private UserDataRepository repository;
    
    /**
     * ユーザーデータリストを取得する.
     * @return ユーザーデータリスト
     */
    @ApiOperation(value = "全ユーザー情報の取得"
        , notes="登録されている全てのユーザー情報を取得します")
    @ApiResponses(value = {
        @ApiResponse(code=200, message="取得した全てのユーザー情報")
    })
    @GetMapping("/users")
    public List<UserData> getAllUserData() {
        return repository.findAll();
    }
    
    /**
     * 指定したIDをもつユーザーデータを取得する.
     * @param id ID
     * @return 指定したIDをもつユーザーデータ
     */
    @ApiOperation(value = "指定したユーザー情報の取得"
        , notes="指定したIDをもつユーザー情報を取得します")
    @ApiResponses(value = {
        @ApiResponse(code=200, message="取得したユーザー情報")
    })
    @GetMapping("/users/{id}")
    public UserData getOneUserData(@ApiParam(name="id"
            , required=true, value="取得するID") @PathVariable long id) {
        Optional<UserData> userData = repository.findById(id);
        // 指定したIDをもつユーザーデータがあればそのユーザーデータを返す
        if(userData.isPresent()) {
            return userData.get();
        }
        // 指定したIDをもつユーザーデータがなければnullを返す
        return null;
    }
    
    /**
     * 指定したユーザーデータを登録する.
     * @param userData ユーザーデータ
     * @return 登録したユーザーデータ
     */
    @ApiOperation(value = "指定したユーザー情報の登録"
        , notes="指定したユーザー情報を登録します")
    @ApiResponses(value = {
          @ApiResponse(code=200, message="登録したユーザー情報")
        , @ApiResponse(code=400, message="指定したユーザー情報のデータ不正")
    })
    @PostMapping("/users")
    public UserData saveUserData(@ApiParam(name="userData", required=true
        , value="登録するユーザー情報") @Valid @RequestBody UserData userData) {
        return repository.save(userData);
    }
    
    /**
     * 指定したユーザーデータを更新する.
     * @param id ID
     * @param userData ユーザーデータ
     * @return 更新したユーザーデータ
     */
    @ApiOperation(value = "指定したユーザー情報の更新"
        , notes="指定したユーザー情報を更新します")
    @ApiResponses(value = {
          @ApiResponse(code=200, message="更新したユーザー情報")
        , @ApiResponse(code=400, message="指定したユーザー情報のデータ不正")
    })
    @PutMapping("/users/{id}")
    public UserData updateUserData(@ApiParam(name="id"
        , required=true, value="更新するID") @PathVariable long id
            , @ApiParam(name="userData", required=true, value="更新後のユーザー情報")
                  @Valid @RequestBody UserData userData) {
        userData.setId(id);
        return repository.save(userData);
    }
    
    /**
     * 指定したIDをもつユーザーデータを削除する.
     * @param id ID
     */
    @ApiOperation(value = "指定したユーザー情報の削除"
        , notes="指定したIDをもつユーザー情報を削除します")
    @DeleteMapping("/users/{id}")
    public void deleteUserData(@ApiParam(name="id"
            , required=true, value="削除するID") @PathVariable long id) {
        Optional<UserData> userData = repository.findById(id);
        // 指定したIDをもつユーザーデータがあればそのユーザーデータを削除する
        if(userData.isPresent()) {
            repository.deleteById(id);
        }
    }
    
    /**
     * 指定したユーザーデータを登録し、登録したデータを取得するURLを返却する.
     * @param userData ユーザーデータ
     * @return 登録したデータとそれを取得するURLを含むエンティティモデル
     */
    @ApiOperation(value = "指定したユーザー情報の登録・取得"
        , notes="指定したユーザー情報を登録し、登録したユーザー情報を取得するURLを返却します。")
    @ApiResponses(value = {
          @ApiResponse(code=200, message="登録したユーザー情報とそれを取得するURL")
        , @ApiResponse(code=400, message="指定したユーザー情報のデータ不正")
    })
    @PostMapping("/users/hateoas")
    public EntityModel<UserData> saveUserDataHateoas(
            @ApiParam(name="userData", required=true, value="登録するユーザー情報") 
                @Valid @RequestBody UserData userData) {
        UserData addUserData = repository.save(userData);
        if(addUserData == null) {
            return null;
        }
        EntityModel<UserData> entityModel = EntityModel.of(addUserData);
        WebMvcLinkBuilder linkTo = 
                linkTo(methodOn(this.getClass()).getOneUserData(addUserData.getId()));
        entityModel.add(linkTo.withRel("getAddUserDataUrl"));
        return entityModel;
    }
}

ユーザーデータエンティティクラスの内容は以下の通りで、@ApiModelアノテーション・@ApiModelPropertyアノテーションでエンティティクラスのモデルやそのプロパティの定義を行っている。

package com.example.demo;

import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;

import com.example.demo.check.CheckDate;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

import javax.persistence.Column;
import javax.persistence.Id;

/**
 * ユーザーデータテーブル(user_data)アクセス用エンティティ
 */
//テーブル名を「@Table」アノテーションで指定
//生年月日の日付チェックを「@CheckDate」アノテーションで指定
@Entity
@Table(name="user_data")
@Data
@CheckDate(dtYear="birthY", dtMonth="birthM", dtDay="birthD"
         , message="{validation.date-invalidate}")
@ApiModel(description="ユーザー情報")
public class UserData {

    /** ID */
    //主キー項目に「@Id」を付与
    @Id
    @ApiModelProperty(value="ユーザー情報を識別するID", example="1")
    private long id;

    /** 名前 */
    //必須チェックを「@NotEmpty」アノテーションで追加
    @NotEmpty(message="{validation.name-empty}")
    @ApiModelProperty(value="名前", example="テスト プリン1", required=true)
    private String name;

    /** 生年月日_年 */
    //カラム名を「@Column」アノテーションで指定
    @Column(name="birth_year")
    @ApiModelProperty(value="生年月日_年", example="2006")
    private int birthY;

    /** 生年月日_月 */
    @Column(name="birth_month")
    @ApiModelProperty(value="生年月日_月", example="12")
    private int birthM;

    /** 生年月日_日 */
    @Column(name="birth_day")
    @ApiModelProperty(value="生年月日_日", example="10")
    private int birthD;

    /** 性別 */
    //性別の値チェック(1,2のいずれかであること)を「@Pattern」アノテーションで追加
    @Pattern(regexp="[1-2]", message="{validation.sex-invalidate}")
    @ApiModelProperty(value="性別", example="2", required=true
        , allowableValues="range[1,2]")
    private String sex;

    /** メモ */
    @ApiModelProperty(value="メモ", example="テスト1", required=false)
    private String memo;
}

その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-rest-api-swagger-edit/demoRestApi



Code VillageはJavaScriptを中心としたサポート体制が充実したプログラミングスクールだったJavaScriptや、JavaScriptのフレームワーク「React」「Vue」を中心にオンラインで学習できるプログラミングスクール...

サンプルプログラムの実行結果

サンプルプログラムの実行結果は、以下の通り。

1) Spring Bootアプリケーションを起動した後で、URL「http://localhost:8085/swagger-ui/」にアクセスすると、以下の画面が表示される。
サンプルプログラムの実行結果_1

2) 上図で「OperateUserData」を開くと、以下のように、各API操作の説明が表示されることが確認できる。
サンプルプログラムの実行結果_2

3) 上図で「/users/hateoas」を開くと、以下のように、APIの説明や戻り値の説明が表示されていることが確認できる。
サンプルプログラムの実行結果_3

4) 上図で「Models」内の「UserData」を開くと、以下のように、ユーザーデータエンティティクラスの各値の定義が確認できる。
サンプルプログラムの実行結果_4

要点まとめ

  • Spring BootのRest APIサービスでSwaggerを利用すると、ドキュメントを定義したり、API実行を行ったりすることができるが、Swaggerのドキュメント定義を編集することもできる。