WebAPIについての説明


## はじめに
新人への説明の為に書きました。
元々は社内勉強会用のスライドのメモだったものを、いい感じに直して公開する事にしました。
「勉強は真面目にするものだ」と考えている人には向きません。
「技術的な事は正確でなければいけない」と考えている人には向きません。
基本的な事から馬鹿丁寧に書いてあるので長いです。時間ある時用の記事です。
誤解を生じるぐらい噛み砕いて簡単に説明してあります。
教科書的に通して読むことでWebAPIが理解出来るように書いてあります。

## 対象者
* htmlとcssは書ける
* phpとjsを主にコピペでしか書けない
* IT関連の基本的な用語も知らない、理解してない
* WebAPI？何それおいしいの？っていう人
* どちらかと言うと営業寄りの部署に所属


## アジェンダ

### 第1部 知識編
WebAPIの

* 仕組みを理解する
* 用語を理解する

### 第2部 実践編
* WebAPIを作る
* WebAPIを利用する



---

## 第1部 知識編
### WebAPIの事前知識
WebAPIの説明の前に、IT関連で必要となる基本的な知識の説明。
表題を見て「意味を知ってるよ」という方は読み飛ばし推奨。
又、各項目は本当に簡単にしか説明して無いので、分からない方は参考先やググると幸せなれる

---

### アプリケーションの種類
アプリケーションを区別する方法は幾つかありますが、ネットワークを使う・使わないで種類わけすると以下の2つになります。

* スタンドアロン
* クライアントサーバ

---

### スタンドアロンとは
スタンドアローン/スタンドアロン (英:stand-alone) とは、他の機器に依存せず単独で動作するアプリケーション。
ネットワークを一切しようせずに動作するアプリケーション。

ここで出て来るだけなので、この記事では以降忘れてOK

例:MicroSoftのWordとか

---

### クライアントサーバとは
> クライアントサーバシステムとは、コンピュータをサーバとクライアントに分け役割分担をして運用する仕組みのことです。
> 
> LANにおける典型的なクライアントサーバシステムとしては、全員が共有しておきたいデータがおいてある「サーバ」があり、そこに一般のユーザーが使う「クライアント」が複数接続されている状態です。
> 
> クライアントはサーバに対して「このデータを送ってほしい」という要求をし、それに対してサーバは要求されたデータを送る、といったことを行います。また、サーバが管理しているプリンタに対して、クライアントから「これを印刷」とデータを送ると、サーバは受け取ったデータをプリンタへ送り、印刷されるといったことを行います。
by [ネットワークお助けマニュアル](http://www.aibsc.jp/joho/otasuke_m/basic/08/02.html)

役割が違う別なコンピュータ同士がネットワークで繋がっているアプリケーション。

例：銀行のATMとかインターネットとか

---

### クライアントサーバ型の特徴

* クライアントとサーバで役割分担
* クライアント多い、サーバ少ない
* クライアントとサーバはネットワークで接続している
* クライアントとサーバで通信する
* クライアントとサーバの両方を使って1つのアプリ(サービス）を提供する
* データを1つのものとして扱える

---

### クライアントサーバ型の仕事の流れ
* クライアントから仕事の依頼
* サーバで頑張る
* サーバから結果を返す
* クライアントで結果を受け取って、いい具合に表示する

---

### サーバとは
英語的にいうと、サービスを提供する人。
クライアントからの依頼を受け取ってサービスを提供するコンピュータやソフト。機能だったりデータだったりする。

前後の文脈でコンピュータ自体のハードだったり、コンピュータ内のソフトだったりするのでややこしい。

#### 種類

* Webサーバ
* DBサーバ
* アプリケーションサーバ
* メールサーバ


*keyword:コック*

---

### クライアントとは
サーバを利用するコンピュータ等。ユーザとやり取りをしてユーザの代理でサーバに問い合わせをする。

* 銀行のシステムでいうとATM
* インターネットを利用する時のクライアントは主にブラウザ。アプリの場合もあるよ。

*keyword:ウエイター*

---

### Webブラウジング

Webブラウジングとはインターネットでサイトを見る事
Webブラウジングもクライアントサーバ型。
クライアントであるブラウザがWebサーバにhttpで通信してコンテンツを表示する。
「http」の事はこの後説明する

---


### プロトコルとは
httpの前にプロトコルの説明。

> コンピューター同士が通信をする際の手順や規約などの約束事。ネットワークでコンピューターが使う言語のようなもので、双方が理解できる同じプロトコルを使わないと通信は成立しない。
by:[コトバンク](https://kotobank.jp/word/%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB-8535)

一言でいうと通信の為のルール。ルールが無いと「相手が何言ってるかわかんない」ってなる。

プロトコルの種類としてはIPとかFTPとかがある。

---

### http(プロトコル)とは

英語的にいうと、```HyperText Transfer Protocol```の略。```HyperText```は```html(HyperText Markup Language)```の事と思えば良い。

単に```http```という時と、```httpプロトコル```っていう時がある。

> インターネット上でWebサーバー（サイトの公開側）と、クライアント（ブラウザ：サイトを閲覧する側）が、相互に通信するために使用される仕組みです。
>
もっと言うと、Webサーバーとクライアント間で、HTML（Webページを作成するための言語）で記載された情報をやりとりするための仕組みです。

by [ゆとり世代のブログ運営論](http://viral-community.com/other-it/http-1873/)

参考[HTTPプロトコルの紹介](http://cai.cs.shinshu-u.ac.jp/sugsi/Lecture/php/http/1-http.html)



---

### httpのポイント

大きく分けてリクエストとレスポンスがある。
日本語でいうと要求と反応。


#### リクエスト(要求)
別な言い方をすると注文。クライアントからサーバに送る。
よくあるのはデータが欲しいとか、データを保存してとかをリクエストする
以下リクエストの中身。

* URL
* メソッド
  * GET：サーバへデータの要求
  * POST：サーバへデータを送る
  * 他にもPUT、DELETEとかあるよ


#### レスポンス(反応)
別な言い方をすると結果。リクエスト受けたサーバがクライアントに返す。
リクエストされたデータの中身とか、登録した結果など。
以下レスポンスの中身。

* ステータスコード（成否とかを数字で表現している）
  * 200：成功
  * 400：リクエストが不正
  * 500：サーバのエラー
* コンテンツ(html)

*keyword:伝票と料理*

---

### Webのブラウジングの流れ
またの名をここまでのまとめ。
ブラウジングはクライアント(ブラウザ)とサーバがhttpという決まりで通信してコンテンツ(html)を出力する。
#### レストランで例えるなら
##### 役割
| レストラン           | ブラウジング     |
|:---------------------|:-----------------|
| ウエイター           | クライアント     |
| コック               | サーバー         |
| 伝票と料理           | http             |

##### 流れ

| レストラン                             | ブラウジング     |
|:---------------------------------------|:-----------------|
| お客さんが店に入店する                 | ブラウザを開く   |
| お客さんが、ウエイターに注文する       | urlの入力        |
| ウエイターは伝票に記入してコックに渡す | リクエスト       |
| コックは料理を作る                     | サーバ処理     |
| コックは伝票と料理をウエイターに渡す   | レスポンス       |
| ウエイターはお客さんに伝票と料理を提供 | コンテンツの表示 |

---

### レストランで例えた説明の詳細1
#### コックのスタンス
* コックはウエイターがどういう方法で注文を受け付けたのかは気にしない。
お店にお客さん来て注文、電話注文、FAX注文、ネット注文何でも良い。とにかく伝票クレというスタンス。
* ブラウジングでいうと、サーバはクライアントが何かは気にしない。PCのブラウザでもスマホアプリでも何でも良い。

---

### レストランで例えた説明の詳細2
#### ウエイターのスタンス
* ウエイターはコックがどう料理するかは気にしない。コックが1人で作ってる。コックが1000人で作ってる。スイーツは隣のお店から買っている、とか別に興味が無い。とにかく伝票と料理をクレというスタンス。
* ブラウジングでいうと、クライアントはサーバがどういう処理しているかは気にしない。DBがMysqlでもOracleでもよいし、ハードウェア的に1台のコンピュータでも複数台のコンピュータでもよいし、サーバから別なサーバを参照しててもよい。

---

### レストランで例えた説明の詳細3
#### 伝票
* 伝票はお客さんの注文が書いてある。実際のレストランではありえないけど、ウエイターに対して、伝票を料理と一緒に渡す時にこの注文が「成功したよ」とか「失敗したよ」とかを伝票に書いて渡すイメージ。口で説明しないで伝票に書くルールになっているイメージ。
* ブラウジングでいうと、ユーザーが指定したサイトのデータをくれとhttpの中に含めてサーバにリクエストを送る。サーバは成功(又は失敗)したよっていう情報とサイトの中身であるhtmlを返す。失敗の時は基本的にはhtmlは空で返す

---

### レストランで例えた説明の詳細4
#### ステータスコード：404
いちばん有名なステータスコードではなかろうか。

* レストランなのに、お客さんがウエイターに車を注文する。ウエイターは律儀にコックさんへその伝票を渡す。コックさんは「そんなのない」って返す時のステータスコード。
* ブラウジングでいうと、ユーザーが指定したURLが、間違っていた・今はもうなくなった等で対応するサイトが無い時

ステータスコードが400番台の場合はリクエストが不正という意味になっている。

---

### レストランで例えた説明の詳細5
#### ステータスコード：500

* お客さんがウエイターに注文する。ウエイターはコックさんへその伝票を渡す。コックさんはキッチンが壊れている等の理由で仕事出来ない。そんな時に返すステータスコード。
* ブラウジングでいうと、サーバがハード的に壊れたとかソフトにバグがあるとかに出る。

ステータスコードが500番台の場合はサーバ側に問題あるという意味になっている。
エンジニアはこれが出ると対応に追われる

---

### レストランで例えた説明の詳細6
#### ステータスコード：200

* お客さんがウエイターに注文する。ウエイターはコックさんへその伝票を渡す。コックさんは料理をつくる。「美味しく出来たぞ！」って時に返すステータスコード。
* ブラウジングでいうと、正常にサイトが表示できた時

ステータスコードが200番台の場合は正常であるという意味になっている。
一般の方々が目にすることは無い。

---

「あれ？おかしいWebAPIの勉強してたはずがWebブラウジングの勉強になってる…。」って方は次から本題です

---

### APIとは
WebAPIの前にAPIの説明

簡単な例えでいうと、プログラムの関数のようなもの。

```js
alert('test');
```
上のコードを実行するとアラートが表示される。`alert()`関数はプログラマが書いた関数では無く、ブラウザ標準で持っている関数。それを規定の方法で利用するとアラートウィンドウを表示する。
これがAPIにあたる。
以下この記事の中ではAPIを関数と読み替えて問題ない。

以下外部のより詳しい説明。
簡単にいうと

> APIは「Application Program Interface」の略で簡単に説明すると、どのアプリーケーションでも共通で使える機能を提供する仕組みです。
> by [SoftBank スマートフォン サービス開発支援サイト](https://www.support.softbankmobile.co.jp/partner_st/home_tech9/column3-4.cfm)

もっと詳しく

> APIは「Application Programming Interface」の略です。アプリケーションプログラミングインターフェイス。
> 　例えば「AというファイルをBという名前でコピーをして、作業完了したら、ポップアップウィンドウを出して知らせる！」というプログラムを作るとします。実際にどんな動きをするのかパートに分けてみると……、
>
> 1. Aというファイルを選択
> 2. 実行ボタンを押すと3のステップへ
> 3. データをコピーする
> 4. コピーされたデータをBという名前を付け保存
> 5. ポップアップウィンドウを出して作業完了を告げる
>
> 　この1.〜5.の作業をすべて一から作成すると、かなり手間が掛かります（マウスの動きを計算して、ウィンドウのデザインを考えて……）。そこで登場するのがAPIです。
>
> 1. ファイルを選択するAPI
> 2. ボタンを押すとプログラムを動かすAPI
> 3. データをコピーするAPI
> 4. ファイルに名前を付けるAPI
> 5. ウィンドウを出してメッセージを出すAPI
>
> と、いろいろな機能があるAPIから、必要なAPIを探し出し組み合わせるだけで、プログラムができてしまうのです。つまりAPIは「特定の機能を持つプログラム部品」なのです。よく使われる命令をAPIにしてみんなで共有してしまえば、非常に効率的に作業ができますね。
>
> ![API](http://image.itmedia.co.jp/ait/articles/0703/13/r85minapi_01.gif)
> 図1　APIを使えば、細かい作業や無駄を省いてプログラムができる
>
> by [＠IT](http://www.atmarkit.co.jp/ait/articles/0703/13/news095.html)

---

### WebAPIとは
ネットワーク越しに利用できる関数。URLが関数名で引数を渡す事で結果が変化する。

以下外部のより詳しい説明。
簡単にいうと
> (APIに)Webサービスを付与したものがWeb APIとなります。
> by [SoftBank スマートフォン サービス開発支援サイト](https://www.support.softbankmobile.co.jp/partner_st/home_tech9/column3-4.cfm)

もっと詳しく

> コンピュータプログラムの提供する機能を外部の別のプログラムから呼び出して利用するための手順・規約(API：Application Programming Interface)の類型の一つで、HTTPなどWebの技術を用いて構築されたもののこと。
> Webサイトに外部のサイトの提供する機能や情報を組み込んだり、アプリケーションソフトからWeb上で公開されている機能や情報を利用する際などに用いられる。
> Web APIで機能を公開しているサーバに対して、インターネットなどの通信ネットワークを通じて依頼内容をHTTPリクエストの形で送信すると、処理結果がHTTPレスポンスの形で送られてくる。送受信されるデータの形式はAPIによって様々だが、Webでよく用いられるXMLやHTML、JSON、各種の画像ファイル形式などが用いられることが多い。
> by [IT用語辞典](http://e-words.jp/w/Web20API.html)

別な切り口で

> 　Web APIとは、ひとことで言えば、インターネット（Web）を経由して、何らかの処理を行うための、手段や決めごと（API）のことです。APIとは、Application Program Interfaceの略で、直訳すると、あるプログラムを、他のアプリケーションから利用するためのインターフェース、という意味になります。
> 　一般的なプログラムでは、関数やサブルーチンと呼ばれるひとかたまりの処理を作成し、それをプログラム内のほかの場所から呼び出すことができます。Web APIを利用すると、それと同じような感覚で、インターネット経由で別のサーバー上にあるプログラムを呼び出し、その結果を受け取ることができるようになります。
> by [CodeZine](http://codezine.jp/article/detail/7169)

google apiや、amazon apiのように有名なWebAPIがある。
また、自分でWebAPIを作って自分だけで利用することも可能。

WebAPIを実行する事をWebAPIを叩くという言い回しがある。
「WebAPIを叩いてみて」と言われ、サーバを叩く(物理)とかやらないように。

---

### WebAPIとブラウジング

WebAPIもhttpの通信でリクエストしてレスポンスを貰う。
ブラウジングと流れは一緒。

以下参考

> 　具体的に「Web API」ではどんなことができるのか紹介しつつ、その仕組みについて見てみましょう。
> 　Web APIとインターネットブラウジングはよく似ています。図2で、その関係を表してみました。
> 　Webのブラウジングは閲覧者であるクライアントからWebブラウザを通して、「このサイトのデータが見たい！」とリクエストを送ります。アクセスを受けたWebサーバは、HTMLやCSSといったテキストデータ、画像や動画などのコンテンツをクライアントに対して提供します。Webサーバから配信されたデータを、ブラウザが受け取り・解釈し、人間に見やすいデザインに再現します。
> ![図2](http://image.itmedia.co.jp/ait/articles/0703/13/r85minapi_02.gif)
> 図2　WebサービスAPIがサーバからデータを取得する仕組み
> 　Web APIでは、PHPやPerl（ほかの言語でもOKですが）といったプログラムが、Webサーバに対して「このデータが欲しい」と、Web APIを使った検索結果をリクエストします。この「データ」とは、例えばYahoo!の検索結果やGoogle Mapのデータだったり、郵便番号と対応する住所だったりします。
> 　リクエストを受け取ったWebサーバ、指定されたWeb APIを使ってデータを検索したり、計算したり、加工したりして、クライアントにデータを返します。データを返す際は、クライアントにとって加工がしやすい「XML形式」が多いようです。クライアントは受け取ったデータを、プログラムが解釈し、Webブラウザで表示したり、CSV形式に変更したりします。
> by [@IT](http://www.atmarkit.co.jp/ait/articles/0703/13/news095_2.html)


---

### WebAPIの一旦のまとめ
* サーバーで用意している関数(機能)をhttpで通信して利用する事。
* 利用するには決め事を守ってリクエストを出す。
* 決まり事とはURLとか渡すデータの名前とかデータの形式とか。
* レスポンスは大体何かしらのデータ。時々画像も。
* データの形式は最近はJSON。一昔前はXMLが主流だった。
* ajax形式で利用される事が多い

---

### JSONとは
データを簡単に表現する仕組み。
ものすごく乱暴に言うとhtmlを簡単にした感じ

---
### JSONのサンプル

chromeのデベロッパーツール>コンソールで以下をコピペして試してみる。

```js:JSONのJS上での例
// 定義
var data = {
	name : 'kobayashi',
	age : 24,
	schols : [
		'千葉小学校',
		'神奈川中学校',
		'東京高校'
		]
};

// 利用
console.log(data.name);
console.log(data.age);
console.log(data.schols);
console.log(data.schols[0]);
```

---

### JSON定義のポイント

* keyとvalueがセットになっている
* valueの種類には文字列、数値、配列、連想配列(オブジェクト)がある
* 文字列
  * シングルクォート(')かダブルクォート(”)で囲む
* 数字
  * そのまま打ち込む。(何かで囲む必要は無い)
* 配列
  * []で囲む
  * keyが数字で省略できる。というか省略する。
  * 利用する時には0から始まる
* 連想配列(オブジェクト)
  * {}で囲む
  * keyが文字
  * keyとvalueの区切りはコロン(:)
* 配列、連想配列(オブジェクト)共通
  * key,valuセットの区切りはカンマ(,)
  * カンマ最後に付けるとエラーになる

詳細はググって下さい。


---

### JSON利用のポイント
連想配列(オブジェクト)の場合は変数名.keyでvalueを使う。
配列は変数名.key[0]のように数字をカギカッコで囲んで利用する。

---

### ajaxとは
「Asynchronous JavaScript ＋ XML」の略で、javascriptを使って非同期にDOM(htmlタグの事でdivタグ、imgタグ等の事)を操作したり、データを取得する実装の方法の1つ。
ajax的アプローチの一部で、WebAPIから都度必要になったデータを取得する事が含まれる。
Googleマップで有名になった。

参考；[いまさら聞けない、“Ajax”とは何なのか？](http://www.atmarkit.co.jp/ait/articles/0708/23/news134.html)

---

### 非同期とは
処理の種類の事で、同期と非同期がある。

同期は処理が直列的に順次実行する処理方法の事。途中に別な処理の依頼があっても後回しにする。
非同期は処理が並列的に同時に実行(される事もある)する処理方法の事。

参考：[いまさら聞けない、“Ajax”とは何なのか？page2](http://www.atmarkit.co.jp/ait/articles/0708/23/news134_2.html)

ブラウジングでの同期的処理はページのリロードにあたる。リロードをするとレスポンスが返ってくるまで他の操作は出来ない。
非同期的な処理はリロードせずに内容を変更したり、他の操作が継続して出来ること。

## 第2部 実践編
WebAPI実践方法

### ブラウザでWebAPI
イメージをつかむ為に、とりあえず郵便番号のWebAPIを試す。
以下をブラウザにコピペかその下のリンクをクリックする。

```URL
http://zipcloud.ibsnet.co.jp/api/search?zipcode=2500011
```
[郵便番号検索API](http://zipcloud.ibsnet.co.jp/api/search?zipcode=2500011)

#### ポイント
search?以降のzipcode=2500011の部分が検索したい郵便番号。

* 「zipcode」がkey
* 「2500011」がvalue
* valueを変更すると結果も変わる
* urlが関数名で引数を渡しているという感じがつかめればOK
* 返ってくる値がJSON形式
* keyを変更すると怒られる
* valueを7桁の数字以外にすると怒られる
* エラーの時だけmessageが入る

色々とurlとかkeyとかvalueとかを変更して上記の内容を実際に確認する。

---

### WebAPIの流れ
しつこいようですが、もう一度確認。

* クライアントから
* httpで
* リクエストして
* サーバー処理して
* レスポンスが返ってくる

大事な事なので何回も言いました。

---

### 自前のWebAPIを作ってみる
サーバーと処理ファイル用意すれば自前のWebAPIを作れます。

ちなみにここではサーバーの事は触れません。
ローカルで試す場合はMAMPとかXAMPを各自ググるか、近くの人に聞いて下さい。

---

### 自前で作る時に事前に決める事
* URLはどうする。通常データは名詞にする。
* リクエストデータの構成。
  * keyとvalue
* レスポンスデータの構成
  * JSONかXMLか
  * keyとvalue
* エラー時のレスポンス
  * レスポンスデータ内で表現するか
  * httpステータスコードで表現するか

リクエスト、レスポンス共に何のデータが必要で、直感的に分かりやすいデータ構成かどうかで決めます。
また、今後の変更に対して柔軟に対応出来るかどうかも考えて決めます。

例えば郵便番号APIで言えば

* URLどうする？
  * `zipcloud.ibsnet.co.jp/api/address`でもよくね？
  * 今後の仕様変更に備えて`zipcloud.ibsnet.co.jp/api/v1/search`のようにバージョン挟む？
* リクエストデータどうする？
  * 1つで7桁数値で貰う？250と0011の2つに分けて貰う？
  * 1つだとしてkeyは`zip`とか、`code`とか`zip_code`とかでもよくね？
* レスポンスデータどうする？
  * `address1`じゃなくて`pref`にする？

といった感じで検討する。

APIの設計についてもっと詳しく知りたい場合は以下の記事が役に立つのではなかろうか。
参考：[5分で絶対に分かるAPI設計の考え方とポイント - ＠IT](http://www.atmarkit.co.jp/ait/articles/1511/19/news022.html)
[api開発に失敗しないための情報収集まとめ : Qiita](http://qiita.com/taiyop/items/78d3a0614be9be77ce41)

---

### サンプルで作るもの
またの名を要件定義といいます。

#### WebAPI(サーバ)
* ユーザリストの一覧
* phpで作る。
* 簡略化の為にDBは使用しない。
* 簡略化の為に入力値(引数に当たるもの)の検証はしない
* ユーザには管理者、オペレーター、ゲストのユーザタイプがある。
* ユーザタイプ毎のデータを返す。
* データはJSON形式

#### 利用する側(クライアント)
* html、js(jQuery)で作成
* ユーザタイプを入力してボタンクリックするとユーザの一覧が表示される。

閉じたWebAPIの利用方法。(同一ドメイン内で使用するの意)

---

### ファイル構成
以下をサーバーに置くと実行出来る。

```
users
 |-api
 |  |-users.php
 |-index.html
 |-api.js
```

---

### WebAPIを作る
またの名をphpファイルを作る。

#### パターンがあるよ
前置きとして、データを返す場合のWebAPIの場合の大まかな流れはほぼ一緒でパターンとして以下のようになるよ。

* リクエストと一緒に渡されたデータを取得
* リクエストデータの検証とか解析
* レスポンスデータの値を作成
  * ここではユーザ一覧
  * 通常はDBの操作(検索、追加、変更、削除)
* レスポンスデータの作成
  * 場合によってはレスポンスデータの検証
  * 検索結果0件の場合とか
  * 変更が正しく行われなかったとか...
* JSON形式でレスポンスを返す。

特にリクエストの検証の部分は、有名なSQLインジェクション(DBを削除出来る攻撃)を防ぐ意味でも必要です。

また、ログインが必須のアプリケーションなら先頭にログインチェックが入ります。

---

### サンプル用phpファイル

```php
// users.php
<?php
/**
 * 結果をjsonで返却する
 *
 * @param  array resultArray 返却値
 * @return string jsonで表現されたレスポンス
 * @author kobayashi
 **/
function returnJson($resultArray){
  if(array_key_exists('callback', $_GET)){
    $json = $_GET['callback'] . "(" . json_encode($resultArray) . ");";
  }else{
    $json = json_encode($resultArray);
  }
  header('Content-Type: text/html; charset=utf-8');
  echo  $json;
  exit(0);
}



/**
 * ユーザの一覧をjsonで返す
 *
 * @param string user_type  a,admin,o,operatorg,guest,のいずれか
 * @return array
 *          string result   OK,NG
 *          array  users   成功時のみ。ユーザリスト
 *              string name ユーザ名
 *              int age 年齢
 *          string message  失敗時のみ。エラーメッセージ
 *
 * @author kobayahshi
 **/
//---------------------------------------------------------
//  処理の開始
//---------------------------------------------------------
//  値の取得（リクエストの受付）
$type = $_REQUEST['user_type'];

//  ユーザリストの初期化
$user_list = [];
//  返却値の初期化
$result = [];

try {
  //  値の検証
  if (empty($type)) {
    throw new Exception("no type...");
  }

  //  ユーザリストの作成
  switch ($type) {
    case 'a':
    case 'admin':
      $user_list = [
        ['name'=>'中居','age'=>18]
      ];
      break;
    case 'o':
    case 'operator':
      $user_list = [
        ['name'=>'木村','age'=>17],
        ['name'=>'森','age'=>16]
      ];
      break;
    case 'g':
    case 'guest':
      $user_list = [
        ['name'=>'香取','age'=>14],
        ['name'=>'草薙','age'=>15],
        ['name'=>'稲垣','age'=>15],
        ['name'=>'岡田','age'=>15],
        ['name'=>'森田','age'=>15],
        ['name'=>'三宅','age'=>15],
        ['name'=>'長野','age'=>15],
        ['name'=>'坂本','age'=>15],
        ['name'=>'井ノ原','age'=>15]
      ];
      break;
    default:
      //  不正な値
      throw new Exception("Invalid value...");
      break;
  }

  //  返却値の作成
  $result = [
    'result' => 'OK',
    'users' => $user_list
  ];
} catch (Exception $e) {
  $result = [
    'result' => 'NG',
    'message' => $e->getMessage()
  ];
}

//  JSONでレスポンスを返す
returnJson($result);
```

他の人に読んで貰う事があるなら、各パート毎に関数化すると可読性が良い。
```createResponseData($type){}```とか

> 対象者が新人なのに、try-catch使ってしまってます。スミマセン。

---

### WebAPIの調査
自分でWebAPIを作って無いなら、まずWebAPIの仕様を調べる。WebAPI(PHP)を作った人に聞くか、仕様書を読むなりして以下の内容を確認する。

* URLは？
* 何のデータをどうやって渡すか
  * keyは？
  * valueの形式や中身は
* 何のデータがどんな形で返ってくるか
  * jsonの形式の場合
    * keyは
    * valueの形式や中身は
  * 一昔前はresultを付けて返す事が多かった。

聞く人もいない、仕様書も無い、想定外の動作をする等の時はphpファイルを直接調査する。
phpファイルを読むコツは以下の通り。

* URL
  * ファイルの設置場所とファイル名。
* リクエストデータのkey
  * `$_REQUEST`,`$_POST`,`$_GET`の中に入ってる
  * `$_REQUEST['user_type']`の場合、keyはuser_type
* リクエストデータのvalue
  * リクエストデータの検証している部分から推測
* レスポンスデータのkey,value
  * JSON形式なら`json_encode()`関数に渡してる値がレスポンスデータの中身。その前の処理を読んでkey,valueを確認
* エラー時のレスポンス方法
  * `header("HTTP/1.1 400 Bad Reques");`とかあればhttpステータスコード使ってる
  * phpファイルでは無く、クライアント側のデベロッパーツールとかで確認

但しフレームワークとか使ってる場合は、上記にあてはまらない事が多い。別途フレームワークの勉強しよう。頑張ろう。

---

### jQueryでWebAPIを利用する。

jQueryの基本的な使い方は理解している事前提ですすめる。分からない場合はやっぱり別途jQueryを勉強しよう。頑b(ry

今回はクリックイベントが発生した時にWebAPIを叩くように作成する。別にクリックイベント以外のreadイベントでも良い。
クライアントからWebAPIへリクエスト出すには、jQueryの`ajax()`関数を使用する。(他にも別な関数あるが今回は触れない)

大きな流れとしては以下のようになる。

* リクエストの下準備
* リクエストの実行
* レスポンスの判定
* レスポンスデータの利用

---

### サンプル用のhtmlとjsファイル

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>WebAPI test</title>
  <style type="text/css">
  /* 見やすいように文字を大きく */
  body,
  input,
  button {
    font-size: 30px;
  }
  </style>
</head>
<body>
  <h2>WebAPI</h2>
  <h3>リクエスト</h3>
  <!-- ユーザタイプを入力するテキストボックス -->
  User Type:<input type="text" name="dataType" /><br>
  <!-- 入力する値の項目 -->
  <ul>
    <li>a:Admin</li>
    <li>o:Operator</li>
    <li>g:Guest</li>
    <li>e:Empty</li>
  </ul>
  <!-- ajax()を実行するボタン -->
  <button data-btn-type="ajax">Data get!</button>
  <br><br>
  <h3>結果</h3>
  <!-- 結果表示用のdivタグ -->
  <div data-result="">未取得</div>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
  <script type="text/javascript" src="api.js"></script>
  <!-- <script type="text/javascript" src="api2.js"></script> -->
</body>
</html>
```


```api.js
$(function() {
  //  クリックイベントにajax処理を登録する
  $('body').on('click', 'button[data-btn-type=ajax]', function(e) {
    console.log('click btn');
    //  リクエストの下準備
    //  リクエスト時に一緒に送るデータの作成
    var send_data;
    send_data = {
      //  テキストボックスの値を設定
      user_type : $('input').val()
    };
    console.log(send_data);
    //  WebAPIを叩く
    $.ajax({
      //  リクエストの内容
      url: 'api/users.php',
      dataType: "json",
      data: send_data,
      //  レスポンス成功時の処理
      success: function(responce) {
        if (responce.result === "OK") {
          console.log(responce);
          $('div[data-result=""]').html(JSON.stringify(responce));
        } else {
          console.log(responce);
          $('div[data-result=""]').html(JSON.stringify(responce));
        }
        return false;
      },
      //  レスポンス失敗時の処理
      error: function(XMLHttpRequest, textStatus, errorThrown) {
        console.log(XMLHttpRequest);
        console.log(textStatus);
        console.log(errorThrown);
        $('div[data-result=""]').html(JSON.stringify("データ取得中にエラーが発生しました。"));
        return false;
      }
    });
    //  フォーカスをテキストボックスに合わせる
    $('input').focus();

    return false;
  });
});
```

ajax()内にリクエスト部分とレスポンス部分がある。

* url,dataType,dataはリクエスト
* success,errorはレスポンス

#### リクエスト

* urlは文字列で
* dataは文字列、数字、JSON形式のどれかで書く

#### レスポンス処理
レスポンスのhttpステータスコードによって処理が変わる

| ステータスコード    | 実行される処理     |
|:----------------|:-----------------|
| 200番代         | success     |
| 400,500番代      | error         |

それぞれ処理を書く。
通常successでもerrorでもhtmlを操作してエンドユーザにお知らせする。

今回のサンプルでは成功時,失敗時ともdiv[data-result]に内容を表示している

---

### デバッグの方法
問題あっても無くてもデバッグして確認する。
特に問題が無いように見えているだけの時があるから注意する。

chromのDev toolで何が起こっているか確認できる。

Network:通信の状態をリアルタイムで確認。
Console:自分で仕込んだログを表示。

意図しない動作やエラーがあれば都度修正してデバッグする。

---

### まとめ

* httpの仕組みを利用していて、リクエストとレスポンスがある
* それはブラウジングもWebAPIも同じ
* データを返すWebAPIを作成する時はパターンがある
* WebAPIを使う前に調査する。用意するもの、返ってくるもの
* jQuery.ajax()でリクエストとレスポンス処理を書ける
* デバッグしながら完成させる

---

### もう少しマシな書き方に直す
以下は余談。良かったら参考にっていうけど…それでも古い書き方ですよ。

---

### WebAPI(PHP)の作成
成功・失敗はレスポンスデータ内で表現せずhttpステータスで表現する。
慣習で`['result']='OK'`等と利用しているが、最近のお作法では宜しくない。

```php
// user2.php
<?php
/**
 * 結果をjsonで返却する
 *
 * @param  array resultArray 返却値
 * @return string jsonで表現されたレスポンス
 * @author kobayashi
 **/
function returnJson($resultArray){
  if(array_key_exists('callback', $_GET)){
    $json = $_GET['callback'] . "(" . json_encode($resultArray) . ");";
  }else{
    $json = json_encode($resultArray);
  }
  header('Content-Type: text/html; charset=utf-8');
  echo  $json;
  exit(0);
}



/**
 * ユーザの一覧をjsonで返す
 *
 * @param string user_type  a,admin,o,operatorg,guest,のいずれか
 * @return array
 *          string result   OK,NG
 *          array  users   成功時のみ。ユーザリスト
 *              string name ユーザ名
 *              int age 年齢
 *          string message  失敗時のみ。エラーメッセージ
 *
 * @author kobayashi
 **/
//---------------------------------------------------------
//  処理の開始
//---------------------------------------------------------
//  値の取得（リクエストの受付）
$type = $_REQUEST['user_type'];

//  ユーザリストの初期化
$user_list = [];
//  返却値の初期化
$result = [];

try {
  //  値の検証
  if (empty($type)) {
    throw new RuntimeException("no type...");
  }

  //  ユーザリストの作成
  switch ($type) {
    case 'a':
    case 'admin':
      $user_list = [
        ['name'=>'中居','age'=>18]
      ];
      break;
    case 'o':
    case 'operator':
      $user_list = [
        ['name'=>'木村','age'=>17],
        ['name'=>'森','age'=>16]
      ];
      break;
    case 'g':
    case 'guest':
      $user_list = [
        ['name'=>'香取','age'=>14],
        ['name'=>'草薙','age'=>15],
        ['name'=>'稲垣','age'=>15],
        ['name'=>'岡田','age'=>15],
        ['name'=>'森田','age'=>15],
        ['name'=>'三宅','age'=>15],
        ['name'=>'長野','age'=>15],
        ['name'=>'坂本','age'=>15],
        ['name'=>'井ノ原','age'=>15]
      ];
      break;
    case 'e':
    case 'empty':
      $user_list = [];
      break;
    default:
      //  不正な値
      throw new RuntimeException("Invalid value...");
      break;
  }

  if (empty($user_list)) {
    header("HTTP/1.1 404 Not Found");
    exit(0);
  }

  //  返却値の作成
  $result = [
    'users' => $user_list
  ];
  //  JSONでレスポンスを返す
  returnJson($result);

} catch (RuntimeException $e) {
  header("HTTP/1.1 400 Bad Reques");
  exit(0);
} catch (Exception $e) {
  header("HTTP/1.1 500 Internal Server Error");
  exit(0);
}
```

---

### JSの作成
`$.ajax()`は公式でも以下の書き方を推奨している。

```js
$ajax()
.done()
.fail()
```

動作は一緒でdoneはsuccess,failはerrorに対応している。
入れ子が深くなったり、続けて非同期処理したい場合に有効。
リクエストとレスポンスが分離していて読みやすい。

```api2.js
$(function() {
  $('body').on('click', 'button[data-btn-type=ajax]', function(e) {
    console.log('click btn');

    //  リクエストの下準備
    //  リクエスト時に一緒に送るデータの作成
    var send_data;
    send_data = {
      //  テキストボックスの値を設定
      user_type : $('input').val()
    };
    console.log(send_data);
    //  WebAPIを叩く
    $.ajax({
      //  リクエストの内容
      url: 'api/users2.php',
      dataType: "json",
      data: send_data,
    })
    .done(function(responce) {                                  //  レスポンス成功時の処理
        if (responce.result === "OK") {
          console.log(responce);
          $('div[data-result=""]').html(JSON.stringify(responce));
        } else {
          console.log(responce);
          $('div[data-result=""]').html(JSON.stringify(responce));
        }
        return false;
      }
    )
    .fail(function(XMLHttpRequest, textStatus, errorThrown) {   //  レスポンス失敗時の処理
        $('div[data-result=""]').html(XMLHttpRequest.status + ' : ' + errorThrown);
        return false;
      }
    );

    //  フォーカスをテキストボックスに合わせる
    $('input').focus();
    return false;
  });

});
```

## ■ やり残し
### ○ 非エンジニアの方々へ
長い記事にお付き合い頂きありがとうございました。ざっくりと概要つかめたかと思います。...つかめましたよね？僕はそう信じてます。お疲れ様でした。

### ○ エンジニアの方々へ
#### ● 正確では無い件
この記事は正確ではありません。理解を助ける為に省略したり、意味を変えたりしています。間違いでは無いが正しくもない、いわゆる「[Lie(s)-to-children](https://qiita.com/daikw/items/bb2c85533cdb2e984a5b)」というヤツです。
ですのでドヤ顔でこの記事の内容を説明したり、根拠にしたりしないで下さい。
エンジニアならもっと正確で詳細な内容を知る必要があります。

#### ● WebAPIの設計
対象読者に説明するには難しいので、どのようにWebAPIを設計すれば良いかに関してはほぼ省略してます。その辺に関してはオライリーの「Web API: The Good Parts」とかを読めばいいと思う。
##### - Restful API
最近のメジャーな設計方式。ググればいい記事がたくさんあり。
##### - GraphQL
上記のRestful APIの問題点を解決するために出てきた新しい方式
#### ● APIドキュメント
わりかしWebAPIの取扱説明書をつくる必要があったりします。
そのためのツール群があります。

* OpenAPI(swagger)
* API Blueprint
* その他

よくよく吟味して使うツールを決めたらいいと思う