Web APIについてまとめノート

#参考書籍
「Web API The GoodParts」

#参考URL
http://qiita.com/mpyw/items/62e6e415f86eb30a5ff4
http://qiita.com/busyoumono99/items/9b5ffd35dd521bafce47
http://bit.ly/1DI5qXd
http://temog.info/archives/programming/jquery-ajax-crossdomain.html

#Web API
Web APIとは、ひとことで言えば、インターネットを経由して、
何らかの処理を行うための、手段や決めごとのこと。

依頼内容をHTTPリクエストの形で送信すると、処理結果がHTTPレスポンスの形で送られてくる。

#データフォーマットの指定方法

-  クエリパラメータを使う方法 (URLを指定)
-  拡張子を使う方法
-  リクエストヘッダでメディアタイプを指定する

※クエリパタメーターを指定する方法がよく使われている。

#APIの手順
① リクエストURIを構築する
② Web APIにリクエストする
③ 結果をパースする

#JSON
http://dev.classmethod.jp/etc/concrete-example-of-json/


#JSONP

-  JSONP はサーバとクライアントでコールバックインターフェイスを取り決めておく必要がある。

-  jQuery の場合は 'callback' というパラメータでコールバック関数を渡す。
(callbackという名前のパラメータ名は多くのJSONP対応のWebAPIが採用している事実上の標準パラメーター)

```php
echo 'callback(' . json_encode(compact('data')) . ')';
```

```js
$.ajax({
    url: 'api.php',
    type: 'post',
    dataType: 'jsonp',
    jsonpCallback: 'callback',
    data: {
          //data
    }
})
```

#$.ajax

```
$.postは$.ajaxの略記
```

```js
$(function () {
    $('#id').click(function () {
        $.ajax({
            url: 'api.php',
            type: 'post',
            dataType: 'json',
            data: {
                //data
            }
        })
        .done(function (response) {
            //処理
        })
        .fail(function () {
            //処理
        });
    });
});
```

#XMLHttpRequest

-  JavaScriptから非同期でHTTP通信を行うオブジェクトの名前が、XMLHttpRequest

#CORS

•「CORS」
http://dev.classmethod.jp/etc/about-cors/
http://hakuhin.jp/js/resource_sharing.html

-  XHTTPRequestでは異なるドメインに対してアクセスを行い、レスポンスデータを読み込むことができない。

-  CORSを行うには、まずクライアントからOriginalというリクエストヘッダを送る必要がある。(大文字小文字は区別される)
 ヘッダには、アクセス元となる生成元を指定する。

-  AllowedOriginは、どこからクロスドメインによるアクセスを可能にするか指定する。

-  IE8,9は、XDomainRequestというXHTTPRequest互換のオブジェクトを利用する必要がある。


-  一覧に含まれている場合は、Access-Control-Allow-OriginというレスポンスヘッダにOriginリクエストヘッダと同じ生成元を入れて返す。アクセス許可を示す。

    ```
Access-Control-Allow-Origin:http://www.example.com
```

-  アクセスしたリソースがセキュリティ上どこのページから読まれても問題がない場合は、Access-Control-Allow-Originヘッダに、*を指定することで、どこからでも読み込めることを明示する。

    ```
Access-Control-Allow-Origin: *
```

- CookieヘッダやAuthenticationヘッダを使ってユーザー認証情報をクライアントが送ってきた場合、サーバーはAccess-Control-Allow-Credentialsヘッダにtrueをセットする。
(認証情報を認識していることをクライアントに返信する)

    ```
Access-Control-Allow-Credentials:true
```

(IE8,9は、認証付きのCORSリクエストに対応していないので利用できない)

#必要知識

```
ajax
XMLHttpRequest.status
textStatus
errorThrown.message

PHP
$.parseJSON( json )

try...catch 文

JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP

連想配列
http://net-labo.net/?p=155
```

#クロスドメイン サンプル/CORS

ソース引用
http://qiita.com/busyoumono99/items/9b5ffd35dd521bafce47

```client.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>WebAPI test</title>
</head>
<body>
  <h2>WebAPI</h2>
  <h3>リクエスト</h3>
  User Type:<input type="text" name="dataType" /><br>
  <ul>
    <li>a</li>
    <li>o</li>
    <li>g</li>
  </ul>
  <button data-btn-type="ajax">Data get!</button>
  <br><br>
  <h3>結果</h3>
  <div data-result="">未取得</div>
　<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
  <script type="text/javascript" src="client.js"></script>

</body>
</html>
```

```client.js
$(function() {
  $('body').on('click', 'button[data-btn-type=ajax]', function(e) {
    var send_data;
    send_data = {
      //  テキストボックスの値を設定
      user_type : $('input').val()
    };

    $.ajax({
      type:'GET',
      url: '(ドメイン)/api/server.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;
  });

});
```

```php:server.php
<?php
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);
}

$type = $_REQUEST['user_type'];
$user_list = [];
$result = [];

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

  //  ユーザリストの作成
  switch ($type) {
    case 'a':
      $user_list = [
        ['name'=>'中居','age'=>18]
      ];
      break;
    case 'o':
      $user_list = [
        ['name'=>'木村','age'=>17]
      ];
      break;
    case 'g':
      $user_list = [
        ['name'=>'森','age'=>14]
      ];
      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);
}
```

#.htaccess

```.htaccess
Header append Access-Control-Allow-Origin: "*"
```