Vanilla JSでGitHubSearchAPIを叩いてみた


##動機
**VanillaJS**・・・フレームワークやライブラリを使わない素のJavaScriptの事。

以下の記事に感銘を受けて、１から勉強をしようとやってみた。
あと、フレームワークを使ったら負けという謎の考えを持っていた。（負の歴史）


[2019年版 最先端のフロントエンド開発者になるために学ぶべきこと](https://qiita.com/baby-degu/items/da30fa71b8f48fffc568)


上記の記事の最初のタスクに挑戦してみた。


APIを叩くのは初心者にとっては最初の難関（だと思っている）

##環境
・node -　v10.16.0
・npm  -　  v 6.9.0

##GitHubSearchAPIの叩き方

以下のURLを参照：


（https://developer.github.com/v3/search/#search-repositories ）

例えば、Reactという名前を含むリポジトリ情報をスター順に取得したい場合、

```
https://api.github.com/search/repositories?q=React+in:name&sort=stars&order=desc
```
のURLで取得できる。

```
{言語名}in:name
```
で{ }に入力された言語が含まれたリポジトリを取得。

```
 sort=stars
```
はスター順に取得することを示している。

##fetch APIを使ってみる

これまた初心者にとっては難関。

###そもそもfetchAPIとは

ざっくりと。
・HTTP通信を行うためのAPI
・ページ全体を再読み込みすることなくURLからデータを取得できる（いわゆる非同期処理）。
・返り値はPromiseが返ってくる。

###使い方

URLを渡してあげる

```js
const searchId = 'React'
fetch(`https://api.github.com/search/repositories?q=${searchId}+in:name&sort=stars&order=desc`)
```
JSON形式にして取得　&&　エラーハンドリング

```js
function fetchSearchInfo(searchId) {
 return fetch(
     `https://api.github.com/search/repositories?q=${serchId}+in:name&sort=stars&order=desc`
 )
     .then((response) => {
       if (!response.ok) {
         throw new Error(`${response.status}: ${response.statusText}`);
       } else {
         return response.json();
       }
     })
     .catch((error) => {
       throw new Error('ネットワークエラー');
     });
}
```
fetchはPromiseを返すので、thenで処理を繋げて書くことができる。
また、catchでエラー処理をまとめることができる。


##実際にやってみる
実践です！

###HTMLの雛形を用意する

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
 <meta charset="UTF-8">
 <title>GitHubAPIApp</title>
 <link rel="stylesheet" href="css/style.css"/>
</head>
<body>
 <header> 
   <div class="header-container">
     <h1 class="header-logo">GitHub Repository Ranking</h1>
   </div>
 </header>
 <main>
   <div class="main-container">
     <p class="maincopy">GitHubの人気リポジトリを読んで、勉強しよう！
     <br>気になるプログラミング言語を入力して、検索してみてください。</p>
     <input id="searchId" type="text" placeholder="検索ワードを入力してください"/>
     <button onclick="main();">検索</button>

     <div id="result"></div>
   </div>
 </main>
  <footer>
    <div class="footer-container">
      <p class="copyright">©Ryu-sou</p>
    </div>
 </footer>

 <script src="src/index.js"></script>

</body>
</html>
```


###入力情報を取得

```index.js
function getSearchId() {
 const value = document.getElementById('searchId').value;
 return encodeURIComponent(value);
}
```
##fetchAPIによるHttp通信

先ほどのやつ

```index.js
function fetchSearchInfo(searchId) {
 return fetch(
     `https://api.github.com/search/repositories?q=${searchId}+in:name&sort=stars&order=desc`
 )
     .then((response) => {
       if (!response.ok) {
         throw new Error(`${response.status}: ${response.statusText}`);
       } else {
         return response.json();
       }
     })
     .catch((error) => {
       throw new Error('ネットワークエラー');
     });
}
```

##async/awaitで非同期処理

上記の関数を用いて、async/awaitで非同期通信を行う。
forで10回反復処理を行い、データを表示させます。

```index.js
async function main() {
 try {
   while (result.firstChild) result.removeChild(result.firstChild);
   const searchId = getSearchId();
   const searchInfo = await fetchSearchInfo(searchId);
   for (let i =0; i < 10; i++) {
     createView(searchInfo.items[i]);
   }
 } catch (error) {
   console.error(`eエラーが発生しました(${error})`);
 }
}
```
awaitは前の処理が終わるのを待ってから、以下の処理を行うので
データを取得　→　反復処理　という処理の流れを同期処理のように記述することができます。

##終わりに

全コードおよび詳細は以下のnoteにまとめてあるので、気になる方はご覧ください！

(https://note.mu/youheyhey0505/n/n63801ef022fc)

##課題

・リクエスト回数には制限がある。
・そもそもタスクは（**今週の**）ランキングトップ10を表示させるだった。(そもそも）