JavaScriptで役立つFetchAPIテンプレ（WebDevTips#3）

こんにちは，くるみです．
これまでは主にpythonに触れてきましたが，最近Javascriptを勉強し始めたので，Webエンジニアを目指す方々へのtipsとして記事を書いていきたいと思います．

前回の記事はこちら▼

https://qiita.com/cocoa_folio/items/666d331d52aa9669d358


#本日のゴール
今回はFetchAPIを使って簡単なブラウザアプリを作ってみようと思います！

![スクリーンショット 2021-08-23 12.15.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1917122/6b2a2c7a-9ed9-69ad-9f0c-3d224a9953f8.png)




#APIとは

FetchAPIの前に，APIについて知らない方もいるのでは？
そこでGoogleで「API とは」と調べてみると...

#####APIとは
>APIとは、「Application Programming Interface（アプリケーション・プログラミング・インタフェース）」の頭文字を取った略語で、ソフトウェアの一部機能を共有する仕組みを指します。具体的には、「機能を公開しているソフトウェア」と「その機能を使いたいソフトウェア」をつなげる窓口のようなものです。API連携を行うメリットには、「ほかのソフトウェアのデータを活用できる」という点もあります。

こちらのサイトに載っているケーススタディがわかりやすかったので共有しますね！
__参考文献__
APIとは？初心者向けに分かりやすく解説します。：　https://products.sint.co.jp/topsic/blog/api
#####ケーススタディ
>郵便番号を入力したら，〇〇県〇〇市〜〜といった住所が返ってくるようなサイトを作りたい
けれど，郵便番号は何十万件もあり，全てを自社のデータベースで運用管理するのは工数＆負荷がかかる...
それなら__API__を使えばいいんじゃない？ 
https://zipcloud.ibsnet.co.jp/api/search?zipcode=3306032
こんなふうに対応するコード（今回はzipcode）をAPIにリクエストすれば，欲しい情報だけが返ってくる！






つまり，なんとなく

__APIは機能を公開しているサイトから，使いたい機能を簡単に取ってこれる！__

ということが分かります．

#FetchAPIとは

APIについてわかったところで，FetchAPIも調べてみましょう！
Googleで「FetchAPI とは」と調べてみると...

#####FetchAPIとは
>Fetch API は (ネットワーク越しの通信を含む) リソース取得のためのインターフェイスを提供しています。 Fetch API を利用すると、リクエストやレスポンスといった HTTP のパイプラインを構成する要素を操作できるようになります。また fetch() メソッドを利用することで、非同期のネットワーク通信を簡単にわかりやすく記述できるようになります。

「非同期」という言葉，聞き覚えありませんか？
前回，前前回の記事をご覧になった方ならわかると思いますが，__Promise__と関係しています！

つまり，なんとなく
FetchAPIとは__httpリクエストを発行する__ものである
fetch()を使うとリクエストの結果が__Promise__で返ってくる

ということが分かりますね

#準備するもの
ここからは実際に開発していきます！
同じ開発環境を作成する場合には，次の手順に沿ってください！
①　VSCodeに拡張機能__open with Live server__を入れる
（vscode左にあるメニューバーから拡張機能を選択し，marketplaceで検索すると出てきます）
②　FetchAPIというファイルを用意し，その中に__index.html__, __sample.txt__, __users.json__というファイルを作成
③ VSCodeの画面を右クリックし，open with Live serverを選択
![スクリーンショット 2021-08-23 12.55.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1917122/c01f3cdc-97eb-1e94-1e27-a9ced1d35b7e.png)



#コードの作成
実際のコードを見てみましょう！少し長めなので部分ごとに説明をしていきますね．

##### サンプルコード全体
```index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Fetch API sandbox</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
</head>
<body>
  <!-- shortcut tips: "button#idでEnterする"-->
  <!-- shortcut tips: "#outputでEnterする"-->
  <div class="container">
    <h1 class="display-4 mb-4">Fetch API Sandbox</h1>
    <div class="d-flex">
      <button class="btn btn-primary mr-4" id="getText">Get text</button>
      <button class="btn btn-success mr-4" id="getUsers">Get JSON</button>
      <button class="btn btn-warning mr-4" id="getPosts">Get API DATA</button>
  </div>
    <hr>
    <div id="output"></div>
    <form id="addPost">
      <div class="form-group">
        <input type="text" id="title" class="form-control" placeholder="Title">
      </div>
      <div class="form-group">
        <textarea id="body" class="form-control" placeholder="Body"></textarea>
      </div>
      <input type="submit" class="btn btn-secondary" value="Submit">
    </form>
  </div>
  <script>
    document.getElementById('getText').addEventListener
    ('click', getText);
    document.getElementById('getUsers').addEventListener
    ('click', getUsers);
    document.getElementById('getPosts').addEventListener
    ('click', getPosts);
    document.getElementById('addPost').addEventListener
    ('submit', addPost);
    function getText(){

      fetch('sample.txt')
      .then((res)=>res.text())
      .then((data)=> {
        document.getElementById('output').innerHTML = data;
      })
      .catch((err) => console.log(err))
    }

    function getUsers(){
      fetch('users.json')
      .then((res)=>res.json())
      .then((data)=>{
        let output = '<h2 class="mb-4">Users</h2>';
        // console.log(data)
        data.forEach(function(user){
          output += `
          <ul class="list-group mb-3">
            <li class="list-group-item">ID: ${user.id}</li>
            <li class="list-group-item">Name: ${user.name}</li>
            <li class="list-group-item">Email: ${user.email}</li>
          </ul>
          `;
        });
        document.getElementById('output').innerHTML = output;
      })
    }

    function getPosts(){
      fetch('https://jsonplaceholder.typicode.com/posts')
      .then((res)=>res.json())
      .then((data)=>{
        let output = '<h2 class="mb-4">Posts</h2>';
        // console.log(data)
        data.forEach(function(post){
          output += `
          <div class="card card-body mb-3">
            <h3>${post.title}</h3>
            <p>${post.body}</p>
          </div>
          `;
        });
        document.getElementById('output').innerHTML = output;
      })
    }

    function addPost(e){
      e.preventDefault();

      let title = document.getElementById('title').value;
      let body = document.getElementById('body').value;

      fetch('https://jsonplaceholder.typicode.com/posts',{
        method:'POST',
        headers:{
          'Accept':'application/json, text/plain, */*',
          'Content-type':'application/json'
        },
        body:JSON.stringify({title:title, body,body})
      }).then((res)=>res.json())
      .then((data)=>console.log(data))
    }

  </script>
</body>
</html>
<!-- VSCodeの拡張機能：open with Live serverを使う-->
<!-- fetchでtxtやJSONファイルから情報を取得し，promiseを返す-->
```

##### 部分ごとに説明
① htmlの構文指定

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Fetch API sandbox</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
</head>
```

②　Fetch API Sandboxというタイトルを表示
基本は，__h1タグ__で囲むだけでタイトルをつけます．２行目の方は装飾をしたverです．

```html
<h1>Fetch API Sandbox</h1>
<!-- <h1 class="display-4 mb-4">Fetch API Sandbox</h1> -->
```
③　ボタンの設置
こちらも基本は，__buttonのidとボタン名__を記述するだけです．４行目以降は装飾をしたverです．

```html
<button id="getText">Get text</button>
<button id="getUsers">Get JSON</button>
<button  id="getPosts">Get API DATA</button>
<!-- <button class="btn btn-primary mr-4" id="getText">Get text</button> -->
<!-- <button class="btn btn-success mr-4" id="getUsers">Get JSON</button> -->
<!-- <button class="btn btn-warning mr-4" id="getPosts">Get API DATA</button> -->
```
④　フォーム欄の設置
フォーム欄には，テキスト入力と提出ボタンを設置します．
placeholderとは，事前にフォーム欄に書かれている灰色の文字のことです．
コメントアウトしているのは，装飾されたverです．

```html
<div id="output"></div>
<form id="addPost">
  <input type="text" id="title" placeholder="Title">
  <textarea id="body" placeholder="Body"></textarea>
  <input type="submit" value="Submit">
</form>

<!-- <div id="output"></div>
<form id="addPost">
  <div class="form-group">
    <input type="text" id="title" class="form-control" placeholder="Title">
  </div>
  <div class="form-group">
    <textarea id="body" class="form-control" placeholder="Body"></textarea>
  </div>
  <input type="submit" class="btn btn-secondary" value="Submit">
</form> -->

```

⑤ スクリプト
ボタンにイベントを付与したり，関数を書いたりしていきます．
__getElementByID().addEventListener()__を使って，getTextボタンにクリック機能をつけます
さらに，__getText()__という関数を作り，事前に用意したsample.txtから文字列を取得するための__fetch()__を記述していきます

__fetch('sample.txt')__とすることで，ローカル環境にあるsample.txtファイルにリクエストを送ることができます．さらに，fetch()は返り値としてPromiseを返すので，__.then__を使って取得したデータの操作をしていきます．エラー処理は__.catch__で行います．

```html
<script>
document.getElementById('getText').addEventListener('click', getText);

function getText(){
  fetch('sample.txt')
  .then((res)=>res.text())
  .then((data)=> {
    document.getElementById('output').innerHTML = data;
  })
  .catch((err) => console.log(err))
}

```
```sample.txt
I am a sample text file
```
また，getUsersボタンでは，__fetch('users.json')__とすることで，ローカル環境にあるusers.jsonファイルにリクエストを送ることができます．

```html
<script>

document.getElementById('getUsers').addEventListener('click', getUsers);

function getUsers(){
  fetch('users.json')
  .then((res)=>res.json())
  .then((data)=>{
    let output = '<h2>Users</h2>';
    data.forEach(function(user){
      output += `
      <ul>
        <li> ID: ${user.id}</li>
        <li> Name: ${user.name}</li>
        <li> Email: ${user.email}</li>
      </ul>
      `;
    });
    document.getElementById('output').innerHTML = output;
  })
}

```
```users.json
[
  {
   "id":1,
   "name":"Rick",
   "email":"rick@email.com" 
  },
  {
    "id":2,
    "name":"Glenn",
    "email":"glenn@email.com" 
   },
   {
    "id":3,
    "name":"Negan",
    "email":"negan@email.com" 
   }
]
```

getPostsボタンでは，APIリクエストが可能なサイトから文字列などの情報を取得し，ブラウザ上で表示させます．
__fetch('https://jsonplaceholder.typicode.com/posts')__とすると，サイトから取ってこれるので便利ですね

```html
<script>
document.getElementById('getPosts').addEventListener('click', getPosts);

function getPosts(){
  fetch('https://jsonplaceholder.typicode.com/posts')
  .then((res)=>res.json())
  .then((data)=>{
    let output = '<h2>Posts</h2>';
    data.forEach(function(post){
      output += `
      <div>
        <h3>${post.title}</h3>
        <p>${post.body}</p>
      </div>
      `;
    });
    document.getElementById('output').innerHTML = output;
  })
}
```
addPostでは，getPostsボタンで取得したデータ100件に対して，フォーム欄に記入してから提出したTitle情報とBody情報を追加登録します．

以上で，完成です！
装飾はBootStrapを使用したので，コードの最初の方にこちらを書いています

```html
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
```
完成品はこちら
![スクリーンショット 2021-08-23 13.49.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1917122/6714d2b3-4f94-5af6-1fa1-179d343e0f3c.png)

ボタンを押すと画像のように用意した文字列やサイトから取得したデータを表示してくれます！

#####参考文献
Fetch API Introduction　：　https://www.youtube.com/watch?v=Oive66jrwBs