10分で体感するAPI

# 背景
社内で営業やカスタマーサポートなどの非開発部門メンバーがAPIについての理解が難しそうだと感じていました。
特に、APIを提供している側と、APIを利用する側の役割の違いが混乱するようです。
APIを提供している社内プロダクトにおいて、利用するお客様側でAPIを呼び出す実装すべき内容について、プロダクト側で実装するものだと思い込んだ質問が来たり、というようなことが度々ありました。
API利用時の登場人物とその役割の違いをイメージするのが難しいのだと思います。

そこで、特にAPIを提供している側と、APIを利用する側の役割を理解するために社内向けに資料を作成しました。
その資料が、社内に限定するような内容でもなかったため、Qiitaにも投稿しておこうと考えました。


# 前提
`API`についてぼんやりしたイメージは持っているのが前提です。<br>
(参考サイト)こちらのサイトの言っていることは理解できるけど実感できない、くらいのレベルだと以下の内容の理解が早いかと。
https://wa3.i-3-i.info/word12428.html

ぼんやりを、もうちょっとはっきりさせたい人向けです。

---
世の中には公開されているAPIがたくさんありますが、今回はサンプルとして日本郵便の[郵便番号検索API](http://zipcloud.ibsnet.co.jp/doc/api)を使います。
※この記事作成時点からAPIの内容が変わっている可能性もありますのでご注意ください。

郵便番号検索APIは、
* このURLに対して`https://zipcloud.ibsnet.co.jp/api/search`
* 7桁の郵便番号([郵便番号検索API](http://zipcloud.ibsnet.co.jp/doc/api)のリクエストパラメータの`zipcode`)を送ると

|パラメータ名|項目名|
|:-:|:-:|
|zipcode|郵便番号|

* 都道府県名など、住所に関する情報([郵便番号検索API](http://zipcloud.ibsnet.co.jp/doc/api)のレスポンスフィールドの`results`部分)等を返してくれます

|フィールド名|項目名|
|:-:|:-:|
|zipcode|郵便番号|
|prefcode|都道府県コード|
|address1|都道府県名|
|address2|市区町村名|
|address3|町域名|
|kana1|都道府県名カナ|
|kana2|市区町村名カナ|
|kana3|町域名カナ|


このAPIを、非開発部門が馴染みやすいようにGoogleスプレッドシートを用いて、GoogleAppScriptを使って利用する演習を行います。
GoogleAppScriptを使ったことが無くても進められるよう意識しています。
このような関係になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/67b3849c-b5ed-173f-016d-500e5c7ef917.png)


# 演習
この章の実施時間が10分のイメージです。
実際に、APIの利用やプログラミングをしたことが無い非開発部門メンバーにやってもらって、10分くらいだろうとタイトルを付けました(短時間で終わるというイメージを付けて、社内でこの資料を参照してもらうハードルを下げるため)。
※この記事作成時点から、GoogleスプレッドシートやGoogle Apps Scriptの仕様変更で以下の流れとは変わっている可能性もありますのでご注意ください。

### 1.雛形シートのコピー
[郵便番号検索APIお試しスプレッドシート雛形](https://docs.google.com/spreadsheets/d/18CqxbkdleyMSG2NSkZHm4-KkFUs9KrhydnXxsDcnJ2o/edit?usp=sharing)
をコピーします。

* メニューバー`ファイル`→`コピーを作成`→`ドキュメントをコピー`→好きな名前を付けて`コピーを作成`

### 2.Apps Script を開く

コピーしたスプレッドシートにおいて、**Apps Script** 画面を開きます
* メニューバー`拡張機能`→`Apps Script`

※好みで`無題のプロジェクト`を好きな名前に変更してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/25270b46-445a-875c-7e80-c9b720bdcb5d.png)

### 3.APIが動くプログラムを貼り付け

今回は実感するだけなので、以下のプログラムを全てコピーし、AppsScriptの**コード.js**の`// ここに貼り付け`に貼り付けます。

<details><summary>貼り付けるプログラム(クリックで開きます)</summary>

(上に空行が必要)

```js
  // 郵便番号検索APIお試しシート を使うという宣言をする
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('郵便番号検索APIお試しシート');

  // 郵便番号検索APIお試しシートの　インプット：郵便番号　の中身を取得
  var postNo = String(sheet.getRange(1, 3).getValue());

  // 入力値が数字7桁かチェック
  if (postNo.match(/^[0-9]{7}$/)) {
    Browser.msgBox("郵便番号：" + postNo + "でAPIを実行します");
  // 入力値が999-9999かチェック
  } else if (postNo.match(/^[0-9]{3}-[0-9]{4}$/)) {
    Browser.msgBox("郵便番号：" + postNo + "でAPIを実行します");
  // 入力値が郵便番号の形式になっていない
  } else {
    Browser.msgBox("郵便番号の形式で入力してください");
    return;
  }

  try {
    var options = {
      'method': 'get',
      "muteHttpExceptions" : true
    }
    // 郵便番号検索APIを実行する
    var response = UrlFetchApp.fetch("https://zipcloud.ibsnet.co.jp/api/search?zipcode=" + postNo, options);

    // APIが正常に終了した場合の処理
    if(response.getResponseCode() == 200) {
      jsonData = JSON.parse(response);

      // シートの　郵便番号　にレスポンスの　郵便番号　をセット
      sheet.getRange(3, 3).setValue(jsonData["results"][0]["zipcode"]);
      // シートの　都道府県コード　にレスポンスの　都道府県コード　をセット
      sheet.getRange(4, 3).setValue(jsonData["results"][0]["prefcode"]);
      // シートの　都道府県名　にレスポンスの　都道府県名　をセット
      sheet.getRange(5, 3).setValue(jsonData["results"][0]["address1"]);
      // シートの　市区町村名	　にレスポンスの　市区町村名	　をセット
      sheet.getRange(6, 3).setValue(jsonData["results"][0]["address2"]);
      // シートの　町域名　にレスポンスの　町域名　をセット
      sheet.getRange(7, 3).setValue(jsonData["results"][0]["address3"]);
      // シートの　都道府県名カナ	　にレスポンスの　都道府県名カナ	　をセット
      sheet.getRange(8, 3).setValue(jsonData["results"][0]["kana1"]);
      // シートの　市区町村名カナ	　にレスポンスの　市区町村名カナ	　をセット
      sheet.getRange(9, 3).setValue(jsonData["results"][0]["kana2"]);
      // シートの　町域名カナ	　にレスポンスの　町域名カナ	　をセット
      sheet.getRange(10, 3).setValue(jsonData["results"][0]["kana3"]);
    // APIがエラーだった場合の処理
    } else {
      throw new Error(response.getResponseCode());
    }
  // APIがエラーだった場合の処理
  } catch(ex) {
    Browser.msgBox("fetch で失敗しました。:" + ex);
  }
```
</details>

貼り付けたら、保存します。
※保存方法は通常通り(Windowsなら`Ctrl` + `s`、Macなら`Command` + `s`、もしくはメニューバーのフロッピーのボタン、等)

### 4.実行準備

`実行`ボタンに先ほど保存したApps Scriptを紐付けます。

* `実行`ボタンを右クリック→点3つの部分をクリック→`スクリプトを割り当て`→`myFunction`を入力して`OK`を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/4fa447dd-7245-4036-5fb4-8df01d68b1ee.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/bcaad973-75ee-757b-d2fc-5e9131a1bcd0.png)

### 5.入力

インプットの郵便番号に、半角7桁数字もしくは郵便番号の形式で調べたい郵便番号を入力してください。
それ以外の形式の場合は、ボタンを押した時にエラーメッセージが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/5a54a175-b409-d1f5-59ef-193924e046d4.png)

### 6.実行

①`実行`ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/bf130c24-42ff-ab8b-745c-7ad557198e4f.png)

(②〜④)最初に実行ボタンを押した時は、AppsScriptを実行するための権限の許可を求めらると思いますので、許可してください。

②`続行`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/8d5fa85a-91f3-aa99-c7a3-f5a7ab51124c.png)

③自分のアカウントを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/bd4e5b26-4a65-f2af-b3f6-4ee84e7bd2b0.png)

④' ※これが表示された場合は`詳細`、表示されない場合は④へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/dd9f423e-60b7-5b6d-4549-a262e0dacf11.png)
`（安全ではないページ）に移動`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/71653596-12e8-af9c-4fce-a8954c0f1a70.png)

④`許可`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/72849aa1-ea5b-01ad-d670-d8cbd221d363.png)

⑤`OK`
※これはプログラムで確認を求めるようにしたので、毎回出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/ef31aae1-845c-94be-7f6f-9c09c7752d29.png)


### 7.結果の確認

アウトプットの欄に、インプットに入れた郵便番号の情報が出てくるのを確認できたら、完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/1343485c-8a40-fc4b-a57c-35c21c5882e1.png)


# 演習内容の解説

演習を通して、出てきた情報を紐付けてみます。

---
`スプレッドシート` → `郵便番号検索API` の流れは、
　郵便番号検索APIの7桁の郵便番号のリクエストパラメータはスプレッドシートのインプットから取得
　　↓
　郵便番号検索APIのURLにくっつける
　　↓
　APIを実行(日本郵便のサーバに対して送信)
ということをしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/80fb3353-517c-81af-a305-a40dde689b22.png)

---
郵便番号検索APIが返してくれた結果(レスポンス)は、スプレッドシートのアウトプットに入れています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/50f8325f-d683-25eb-ae39-d1dad054430a.png)

---
##### 余談
実はブラウザのURL欄にこんな感じで`zipcode`付きで入力しても、
`https://zipcloud.ibsnet.co.jp/api/search?zipcode=2200012`
結果を返してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367907/dd8cd16b-b193-3139-ca93-229879a47fb3.png)


# 最後に

以上の演習と合わせて、
> Webシステムを例とすると、人間がWebブラウザを通して、システムを使います。
> しかし、人間じゃなく、とあるシステムが別のシステムを使いたい場合があります。
> APIは、人間がWebブラウザを介するように、自身以外のシステムがAPIを介してシステムを使えるようにしたものです。(APIは`Application Programming Interface`なので、何となくしっくり来るんじゃないでしょうか)

という説明をしています。

実際に手を動かしてみることで、そのようなイメージを具体化するのに役立てばと考えました。
自分自身においても、実際にAPIを利用するプログラムの実装をするまでは、ぼんやりとしか理解できていませんでした。

この資料を作成以降、社内でのAPIに関する質問の解像度が上がったような気がしなくもないので、いちおう作って良かったんじゃないかと思っています。