LoginSignup
15
15

More than 1 year has passed since last update.

SpringbootでAPIを作成し仕様書をswaggerで自動作成する

Last updated at Posted at 2021-05-30

目的

springbootでOpenAPI(swagger)を導入して簡単なアプリを作成する

  • OpenAPIの使い方を学習すること
  • APIの操作方法を学ぶこと
  • CRUDを自作する

開発環境

  • ProductName: macOS
  • ProductVersion: 11.3
  • IDE: eclipse_2021_03

REST(REpresentational State Transfer)とは?

  • 設計方法のこと
    • HTTPで定義されているメソッドの使用する(例:サーバ上にリソースを作成するにはPOST、リソースを取得するにはGET、リソースの状態を変更/更新するにはPUT、削除するにはDELETE)
    • ステートレスであること(サーバーはクライアントのことを一切覚えない)
    • 処理結果をHTTPステータスコードで返す
  • 様々な設計原則の集合

RESTful API(REST API)とは?

  • RESTの設計原則に従ったAPI
  • RESTful Webサービスとの通信を可能になる

Swaggerとは?

SwaggerはOAI(Open API Initiative)が採用しているREST APIを構築するためのオープンソースのフレームワーク

なぜSwaggerなのか?

  1. OSSで最も使われているAPIドキュメント自動生成ツール
  2. 各フレームワークで利用可能
    • Spring MVC
    • Swagger-PHP
    • Ruby用のgrape-swagger
  3. Swaggerツールが利用可能
    • Swagger Editor 
      • APIドキュメントの作成、新しいAPIの記述、既に記述したAPIの編集、リアルタイムにフィードバックでSwagger定義のレンダリングをサポート
    • Swagger UI
      • 開発者向けに、複数のプラットフォームに対応した自作のドキュメントを作成。
    • Swagger Codegen
      • 開発者がクライアント用のコード・ライブラリーを作成。サーバー・スタブやSDKを生成することで、より高速なAPIをより早く構築することが可能
    • Swagger Inspection
      • SwaggerがあらゆるAPIのOpenAPIドキュメントを自動生成してテストすることができるツール。また、テストはクラウドに自動保存される

API完成画面

image.png

フォルダ構成

image.png

アプリ作成

新規springスターター・プロジェクトを選択

image.png

image.png

openapiを追加

pom.xml
	<dependencies>
        <!dependenciesタグ内に、以下を追加します>
        <!ここから>
		<dependency>
		     <groupId>org.springdoc</groupId>
		     <artifactId>springdoc-openapi-ui</artifactId>
		     <version>1.5.9</version>
		</dependency>
        <!ここまで>
	</dependencies>
Spring REST Docs と OpenAPIの違いの説明はこちらの記事を参考に

モデルを作成

image.png

image.png

/spring-rest3/src/main/java/dev/simpleboot/rest/model/Task.java
package dev.simpleboot.rest.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Entity
public class Task {
    @Id
    @GeneratedValue
    private Long id;

    @NotBlank
    @Size(max = 255)
    private String name;

    @NotNull
    private Boolean completed = false;
}

リポジトリを作成

image.png

image.png

/spring-rest3/src/main/java/dev/simpleboot/rest/repository/TaskRepository.java
package dev.simpleboot.rest.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import dev.simpleboot.rest.model.Task;

public interface TaskRepository extends JpaRepository<Task, Long> {

}

コントローラを作成

image.png

image.png

package dev.simpleboot.rest.controller.v1;

import java.util.List;

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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import dev.simpleboot.rest.model.Task;
import dev.simpleboot.rest.repository.TaskRepository;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;

@RequestMapping("api/v1/tasks")
@RequiredArgsConstructor
@RestController
public class TaskController {

    private final TaskRepository repository;

    @Operation(summary = "タスクを全権取得します")
    @GetMapping("/")

    List<Task> findAll() {
        return repository.findAll();
    }

    @Operation(summary = "タスクを登録します")
    @PostMapping("/")
    Task save(@RequestBody Task task) {
        // taskに値が格納してあるため、そのまま保存ができる
        return repository.save(task);
    }

    @Operation(summary = "タスクを1件取得します")
    @GetMapping("/{id}")
    Task findById(@PathVariable Long id) {
        // idに値が格納してあるので、そのまま検索に利用できます
        return repository.findById(id).get();
    }

    @Operation(summary = "タスクを更新します")
    @PutMapping("/{id}")
    Task save(@RequestBody Task newTask, @PathVariable Long id) {
        return repository.findById(id).map(task -> {
            // 該当IDが存在する場合、更新する
            task.setName(newTask.getName());
            task.setCompleted(newTask.getCompleted());
            return repository.save(task);
        }).orElseGet(() -> {
            // 該当IDが存在しない場合、登録する
            newTask.setId(id);
            return repository.save(newTask);
        });
    }

    @Operation(summary = "タスクを削除します")
    @DeleteMapping("/{id}")
    void deleteById(@PathVariable Long id) {
        repository.deleteById(id);
    }
}

アプリを起動する

image.png

ブラウザで localhost:8080/swagger-ui.html にアクセス

image.png

Swagger UIにタイトルを追加する

/spring-rest3/src/main/java/dev/simpleboot/rest/SpringRest3Application.java
package dev.simpleboot.rest;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;

@OpenAPIDefinition(info = @Info(title = "Task API", version = "1.0.0", description = "これはTaskアプリケーションのAPIです"))
@SpringBootApplication
public class SpringRest3Application {

    public static void main(String[] args) {
        SpringApplication.run(SpringRest3Application.class, args);
    }

}

ブラウザで localhost:8080/swagger-ui.html にアクセス

image.png

  • ✅ドキュメントの名前が変わっている
  • ✅説明が追加されている

まとめ

  • OpenAPIを使うにはpom.xmlにspringdoc-openapi-uiを追記する

参考記事(いつもありがとうございます)

参考リポジトリ

15
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
15