Dog APIというAPIを叩いて癒されよう

## はじめに
今年度からIT未経験の新卒としてこの業界で働いています。
開発案件参画を目指して日々の学習での気付きやTipsを発信していきます。
よろしくお願いいたします。

:::note warn
新卒1年目の備忘録程度の初心者記事となります。
内容に誤りのある可能性がありますので、誤りがある際はご指摘お願いいたします。
:::

今回は、現場で要件定義、設計をする中で「知識としてAPIという用語については理解しているけど、APIを使った経験もないし使用する具体的なイメージがあまり湧かないや...」という状況になり、APIについて調べていた際に見つけたAPIについての紹介となります。

その名も、***「Dog API」***

## 記事の概要
・Dog APIの紹介
・APIを叩いてみる
・Dog APIから取得した情報を画面に表示させてみる（HTML,Javascript）

## Dog APIとは？
大量の犬の画像を提供している癒し系APIです。
巷で話題のNEW　KAWAIIではなくTraditional　KAWAIIですね。

https://dog.ceo/dog-api/

※他にも面白いAPIがあるので気になる方は是非。
https://qiita.com/danishi/items/42d8adf6291515e62284

## 実際にAPIを叩いてみる
さて、ここで可愛い犬たちが拝めるのは分かりました。
実際にこの子達を呼び出すためにはどうすれば良いのでしょうか。

chatGPTに聞いてみたところ以下の手順が必要なようです。

1.APIのエンドポイントを把握
2.認証方法を確認（APIキーやOAuth）
3.リクエスト方法（GET, POSTなど）を理解
4.必要なパラメータやリクエストボディを準備
5.リクエストを実行（curl, fetch, axios, requestsなどを使う）
6.レスポンスを解析し、必要なデータを取得
7.エラーハンドリングを実装

ということでやっていきましょう。
### 1.APIのエンドポイントを把握
エンドポイントはDogAPIの公式ドキュメントに記載があります。
意外と種類が豊富ですね。
ここでは主なものを抜粋して記載します。

①全犬種のリストを取得
https://dog.ceo/api/breeds/list/all
②全ての犬からランダムで取得
https://dog.ceo/api/breeds/image/random 
③全ての犬からランダムで指定数を取得
https://dog.ceo/api/breeds/image/random/3 
④指定した犬種の画像を取得
https://dog.ceo/api/breed/hound/images
⑤指定した犬種の画像をランダムで取得
https://dog.ceo/api/breed/hound/images/random

など他にもいくつかありました。

### 2.認証方法を確認（APIキーやOAuth）
今回はパスします。

### 3.リクエスト方法（GET, POSTなど）を理解
代表的なリクエストは以下の4つです。
・GET: データを取得する
・POST: 新しいデータを作成する
・PUT: 既存のデータを更新する
・DELETE: データを削除する

私は上記の中でPOSTとPUTの区別がイマイチ理解出来ませんでした。
2つの区別は冪等性の有無（同じ操作を何度繰り返しても、同じ結果が得られるか）によってなされます。
参考：https://zenn.dev/gostachan/articles/e83aa6697c0c4b

今回はGETリクエストを行います。

### 4.必要なパラメータやリクエストボディを準備
APIのドキュメントを確認したところ、今回クエリパラメータは存在しませんでした。

### 5.リクエストを実行（curl, fetch, axios, requestsなどを使う）
今回はfetchを使ってAPIを叩いてみます。
エンドポイントは以下で、全ての犬からランダムで情報を取得します。
https://dog.ceo/api/breeds/image/random
```javascript:javascript
fetch("https://dog.ceo/api/breeds/image/random") 
    .then((response) => {
      return response.json();
    })
    .then((myJson) => {
      //データを使用する処理を記載
    });

```
<details> <summary>解説</summary>

```javascript:javascript
fetch("URL")

```
fetchメソッドの引数のURLからレスポンスデータを取得しています。
```javascript:javascript
    .then((response) => {
      return response.json();
    })
```
fetchしたデータを引数として受け取り、
今回は取得したデータをjsonメソッドを使用してJson形式に変換しています。
```javascript:javascript
    .then((myJson) => {
      //データを使用する処理を記載
    });
```
ここで実際にデータに対して行う処理を記載します。
</details>

### 6.レスポンスを解析し、必要なデータを取得
レスポンスデータは以下の通りになります。
message内にhound-plottとあるように、返却データから犬種情報も得られそうなので画面に表示する際にはこちらも活用することにします。

```json:json
{
    "message": "https://images.dog.ceo/breeds/hound-plott/hhh_plott002.jpg",
    "status": "success"
}
```
### 7.エラーハンドリングを実装
今回は省略しますが、以下の記事を参考にしようと思っています。
https://zenn.dev/junki555/articles/4ab67fc78ce64c

fetchではネットワークエラーに限りcatchが動くので、それ以外のエラーに関しては別途処理する必要があるというのは勉強になりました。

## 画面に表示させてみる
取得したデータを使い、画面に表示を行いたいと思います。
ボタン押下で画像が表示されるという非常に簡単な画面をHTML,Javascriptで作成します。

完成した画面がこちらです。
1匹より2匹の方がより癒されるので2匹表示させることにしました。
静止画では本当に切り替わっているか分からないですが、画面上部のボタンを押下することでランダムに取得した画像を表示させています。

![inu1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3814555/f79db363-c3bd-ea11-318f-e3d7bc92e651.png)

![inu2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3814555/ad50e6ae-ea3c-88dd-2b59-61af9bbac6e3.png)

::: note warn
改修案
左の画像の描画⇒右の画像の描画となり表示タイミングにかなりズレがあることが気になるため、2枚の画像を(ほぼ)同時に表示させる方法がないのか模索中
:::

<details><summary>コード詳細</summary>

```html:index.html
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link href="./src/input.css" rel="stylesheet">
</head>
<body>

  <button id='click'>いぬ🐩🐩🐩</button>
  <!-- APIから取得した犬種と画像を表示する -->
  <div class="flex">
    <div>
  <div>犬種：<span id='type'></div>
  <div><img id='image' class="image"></div>
    </div>
    <div>
  <div>犬種：<span id='type2'></div>
  <div><img id='image2' class="image"></div>
    </div>
</div>
  <script src="js/index.js"></script>
</body>
</html>
```
```javascript:index.js
const button = document.getElementById("click");
const type = document.getElementById("type");
const image = document.getElementById("image");
const type2 = document.getElementById("type2");
const image2 = document.getElementById("image2");

// ボタンをクリックしたらイベント発動
button.addEventListener("click", () => {
  fetch("https://dog.ceo/api/breeds/image/random") // APIのURL
    .then((response) => {
      return response.json();
    })
    .then((myJson) => {
      // imgタグに取得したURL画像を入れる
      image.src = myJson["message"];
      // 取得したURLをスラッシュ記号で分割し、犬種を表した要素を取得する
      const breed = myJson["message"].split("/")[4];
      type.innerText = breed;
    });

  fetch("https://dog.ceo/api/breeds/image/random") // APIのURL
    .then((response) => {
      return response.json();
    })
    .then((myJson) => {
      // imgタグに取得したURL画像を入れる
      image2.src = myJson["message"];
      // 取得したURLをスラッシュ記号で分割し、犬種を表した要素を取得する
      const breed = myJson["message"].split("/")[4];
      type2.innerText = breed;
    });
});
```
</details>


## まとめ
今回は、癒される「Dog API」の紹介と実際にAPIを叩いて画面への表示を行いました。
最後までご覧いただきありがとうございます。
今後はTypescript、Reactについても備忘録を残していけたらと考えています。