Java(SpringBoot)でのAPIの呼び方、使い方

## 前提
動的Webアプリケーションを
まぁようはServlet Service Daoとかを作り
サーバーとの通信でWebページを作れるようになって…
フレームワーク無しで勉強して、その後Springフレームワークを勉強して…
けどAPIがわからない！APIってなんだよ！

そんなあなたへ

Spring Bootを使った、APIの呼び方を
備忘録がてら書きます！

※SPAでフロント側からAPIを呼ぶやつも今後紹介します！今回はサーバー側だけ！

## APIとは
アプリケーションプログラミングインターフェース
難しいことはないです。ただのメソッドです。
外部のサーバーのメソッドを呼ぶってだけです。
他の人の家にたずねて、野菜分けてもらうみたいな感じです。

いつもは自分の家の中の食材使って、自身のサーバー内のメソッドを使って、サービスをだしてたけれど
やっぱ他のも使いたい！ってことで、外部のメソッドを呼びたい時があるのです

## やり取りはJSON
ヤモリじゃないよ 13日の金曜日でもないよ
JavaScript Object Notation
`{ id:1245, name:'たろう', comment:'わっほい' }`
こういうやつ！
変数の名前:中に入ってるやつ
をカンマで区切っていく書き方
これがJSONっていう書き方です

急にそんな事言われても…って感じだよね

そもそも…
## APIもメソッド
なので、引数があって、戻り値があります。
基本API呼ぶのはServiceです！

`自分の家→(トマトあげる！)→相手の家`
`自分の家←(おかえしにキュウリ！)←相手の家`

つまり

`自分のService→(リクエスト)→相手のService`
`自分のService←(レスポンス)←相手のService`

このリクエストやレスポンスにはBeanだったりModelというかEntityというか、まぁそういうのを使います

つまりこういうやつ！

あげるやつ！トマトEntity！

```java:TomatoEntity.java
@Component
public class TomatoEntity {
    //id
    private String id;
    //名前
    private String name;
    //コメント
    private String comment;

    //以下、getterとsetter
    public String getId() {
      return id;
    }
    public String setId(String id) {
      this.id = id;
    }

    public String getName() {
      return name;
    }
    public String setName(String name) {
      this.name = name;
    }

    public String getComment() {
      return comment;
    }
    public String setComment(String comment) {
      this.comment = comment;
    }

    //Eclipseだと
    //Alt+Shift+Sのメニューから
    //Alt+Rでgetter setter生成を選択
    //Alt+Aで全部選択
    //Alt+Rで作成！って
    //ずっとAlt押しっぱなしでやっていけばすぐに作れます！
}
```


レスポンス用のキュウリEntity!

```java:KyuuriEntity.java
@Component
public class KyuuriEntity {
    //日付
    private Date day;
    //メッセージの配列
    private List<String> message;

    //以下、getterとsetter
    public Date getDay() {
      return day;
    }
    public Date setDay(String day) {
      this.day = day;
    }

    public List<String> getMessage() {
      return message;
    }
    public list<String> setMessage(List<String> message) {
      this.message = message;
    }

    //まぁSpringならアノテーションで
    //getter setterあるので
    //メソッド作らなくても大丈夫ですが...
}
```
なので

`自分のService→(TomatoEntity)→相手のService`
`自分のService←(KyuuriEntity)←相手のService`


てことです！


んで、これをJSONに変換してやり取りするので

`自分のService→(TomatoEntity)→(JSONになったTomato)→相手のService`
`自分のService←(KyuuriEntityに戻す)←(JSONのKyuuri)←相手のService`

とまぁこんな感じで認識しとけばおｋ

JSONでやり取りしてるよってことが分かれば特に意識する必要なし！


## もっと具体的に！
まぁふわふわしてて、実態を捕えずらいというか、なんか分かりにくいって思うので
具体例をどうぞ(いろいろ変だけど分かりやすさ重視！)


```java:CallApiService.java
@Service
public class CallApiService {
    //まずはリクエストを作る
    TomatoEntity tomato = new Tomatoentity();
    tomato.setId("831");
    tomato.setName("トマト");
    tomato.setComment("おいしいよ");

    //APIに送るリクエストを作る
    RequestEntity<TomatoEntity> request = RequestEntity
        .post(new URI("http://kyuuri.api"))
        .accept(MediaType.APPLICATION_JSON)
        .body(tomato);

    //APIからレスポンスが返ってくる
    ResponseEntity<KyuuriEntity> response = restTemplate
        .exchange(request, Kyuuri.class);
}
```

解説！！
#### ・リクエスト
先ほど設定したトマトEntityを作り、外のAPIにリクエストとして投げます
`RequestEntity`はSpringフレームワークの提供する型
　　これがAPIに送るトマトを包んでくれる箱です
　　箱にトマトEntityを詰めて届けるのです
`new URI`はJava.net.URIです
　　住所ですね。わかるっしょ
`.accept()`の`MediaType.APPLICATION_JSON`でJSON型に変換します
　　さっき書いたとおり、JSONでやり取りするよってこと！
`.body()`が、リクエストの中身の情報
　　今回は上で作ったトマトEntity詰めてるよ

```java:つまりこういうこと
RequestEntity<送るentityの型> 好きな名前 
    = 
    RequestEntity.post(送る先のurl).accept(jsonにする).body(送るentityの中身)
```

#### ・レスポンス
※今回はRestTemplete使うバージョンです
見やすさのためにもっかい書いとくね

```java:CallApiService.java
@Service
public class CallApiService {
    //まずはリクエストを作る
    TomatoEntity tomato = new Tomatoentity();
    tomato.setId("831");
    tomato.setName("トマト");
    tomato.setComment("おいしいよ");

    //APIに送るリクエストを作る
    RequestEntity<TomatoEntity> request = RequestEntity
        .post(new URI("http://kyuuri.api"))
        .accept(MediaType.APPLICATION_JSON)
        .body(tomato);

    //APIからレスポンスが返ってくる
    ResponseEntity<KyuuriEntity> response = restTemplate
        .exchange(request, Kyuuri.class);
}
```

先ほど設定したキュウリEntityに対し、外のAPIからレスポンスが返ってきます
だからAPIからの戻り値の形わかってないとだめだよね
`ResponseEntity`はSpringフレームワークの提供する型
　　これがAPIから帰ってくるキュウリを包んでくれる箱です
　　箱にキュウリEntityが詰まって届くのです
`restTemplete`っていう便利な奴があるんだよ
詳しくは
[RestTemplete公式リファレンス](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html)
`.exchange`はRestTempleteのメソッドで
　　リクエストがAPIに入ったら、戻り値を、指定した型として出力するよっていう
　　まぁようはこれがAPIの(引数, 戻り値)ってことだぬ

```java:つまりこういうこと
ResponseEntity<戻るentityの型> 好きな名前 = restTemplete
                    .exchange(リクエストの変数名, 戻る型.class);
```

本来ならもうちょっとメソッドが続いて
接続やレスポンスのタイムアウト設定だったり
認証だったり、このあとにバリデーションが続いたり
エラーステータスコードだかなんだかがくっついてくるのですが

APIはこうやるんだ！ってことを理解するならこれだけで十分かと！

そしたら最後に

```java:CallApiService.java
@Service
public class CallApiService {
    //まずはリクエストを作る
    TomatoEntity tomato = new Tomatoentity();
    tomato.setId("831");
    tomato.setName("トマト");
    tomato.setComment("おいしいよ");

    //APIに送るリクエストを作る
    RequestEntity<TomatoEntity> request = RequestEntity
        .post(new URI("http://kyuuri.api"))
        .accept(MediaType.APPLICATION_JSON)
        .body(tomato);

    //APIからレスポンスが返ってくる
    ResponseEntity<KyuuriEntity> response = restTemplate
        .exchange(request, Kyuuri.class);

    //返ってきた値を取り扱う
    KyuuriEntity kyuuriResponse = response.getBody();
}
```

`.getBody()`で、こっちで設定した通りのキュウリEntityが取り出せるし
　　おまけにAPIからの戻り値が中に入っているので
　　これで、よそのAPIをたたけたことになりますね！


# で？
うん。具体的にはみんな実験していろいろ試してくれい。
あくまで備忘録がてら書いているので~~雑だったりするけれど~~参考になればうれしいです！

そいじゃまた！