SpringでREST APIを呼び出すアプリケーションを作った

REST APIを呼び出して、レスポンスをJavaクラスのインスタンスとして受け取るアプリケーションを作りました。

APIサーバーのモックをローカルにたてて、アプリケーションからモックサーバーへリクエストを送信する構成にしています。

モックサーバー

Json Serverを使用しています。 複雑な設定が不要で、気軽にモックを作成できるツールです。

npmでインストールできます。

% npm install -g json-server

インストールできたらdb.jsonを作成して、

{
  "quotes": {
    "type": "success",
    "value": {
      "id": 10,
      "quote": "{\"id\":1,\"content\":\"Hello, User!\"}"
    }
  }
}

db.jsonを置いているディレクトリで↓コマンドを実行すると、モックサーバーが立ち上がります。

% json-server --watch db.json

デフォルトだと3000番portで起動しているので、↓のように動作確認できます。

 % curl localhost:3000/quotes
{
  "type": "success",
  "value": {
    "id": 10,
    "quote": "{\"id\":1,\"content\":\"Hello, User!\"}"
  }
}    

レスポンスをJavaインスタンスへ変換

APIサーバーからのレスポンスをJavaインスタンスに変換する際はRestTemplateを使います。↓のようにすると、getForObject()第一引数で指定したURLへGETリクエストを送信して、レスポンスをQuoteの形式にマッピングして、インスタンスを生成してくれます。

Quote quote = restTemplate.getForObject("http://localhost:3000/quotes", Quote.class);

ドメインクラス

今回のレスポンスjsonは↓の形式です。

{
  "type": "success",
  "value": {
    "id": 10,
    "quote": "{\"id\":1,\"content\":\"Hello, User!\"}"
  }
}   

これを表現するために、QuoteValue、2つのjavaクラスをドメインクラスとして使用します。

Quote.java

@JsonIgnoreProperties(ignoreUnknown = true)
public class Quote {

  private String type;
  private Value value;

  public Quote() {}
  以下setterとgetter ...

Value.java

@JsonIgnoreProperties(ignoreUnknown = true)
public class Value {

  private Long id;
  private String quote;

  public Value() {}
  以下setterとgetter ...

@JsonIgnoreProperties(ignoreUnknown = true)とすると、ドメインクラスに存在しないプロパティがJsonに含まれていた場合、無視されます。ignoreUnknown = falseにした場合は無視されずにエラーが発生します。

リクエスト送信

アプリケーションの実行時にリクエスト送信、レスポンス変換を行います。変換結果のQuoteをlogに出力して確認できるようにしています。

@SpringBootApplication
public class ConsumingRestApplication {

    private static final Logger log = LoggerFactory.getLogger(ConsumingRestApplication.class);

    ...

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }

    @Bean
    public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
        return args -> {
            Quote quote = restTemplate.getForObject("http://localhost:3000/quotes", Quote.class);
            log.info(Objects.requireNonNull(quote).toString());
        };
    }
}

動作確認

アプリケーションを実行すると↓ログが出力されていて、意図した動作をしているのが分かります。

INFO 33076 --- [           main] c.e.s.SpringBootRestConsumerApplication  : Quote{type='success', value=Value{id=10, quote='{"id":1,"content":"Hello, User!"}'}}

参考文献

https://spring.io/guides/gs/consuming-rest/