アニメ情報APIをJavaScriptから使用する

[Google Cloud Endpointsでアニメ情報API](http://qiita.com/kumo2ji/items/248b4e348af68d9c317e)で作成したAPIをTypeScriptで呼び出す。
Google Cloud Endpointsで作成したAPIはGoogleが用意しているライブラリ(GAPI)を使って簡単に利用することができる。
詳細は「[Using Endpoints in a JavaScript Client](https://cloud.google.com/appengine/docs/java/endpoints/consume_js)」。
TypeScriptから利用するためにGAPIの型定義ファイルをダウンロードする。
Visual Studioの場合はNuGetで検索すれば出てくる。
![gapi nuget.PNG](https://qiita-image-store.s3.amazonaws.com/0/56307/bae05267-63c4-21da-aade-d6c58da9658c.png)

加えてアニメ情報API用の型定義ファイルを作成する。([gapi.animeinfo.d.ts](https://github.com/kumo2ji/AnimeInfoClient/blob/master/AnimeInfoClientType/Scripts/typings/gapi/gapi.animeinfo.d.ts))

```ts:gapi.animeinfo.d.ts
declare namespace gapi.client {
    export function load(name: string, version: string, callback: () => any, root: string): void
    namespace animeInfo {
        namespace get {
            export function anime(): HttpRequest<Response<AnimeInfo>>
            export function anime(request: GetAnimeInfoRequest): HttpRequest<Response<AnimeInfo>>
        }

        export interface Response<T> {
            items: Array<T>
            nextPageToken: string
        }
        export interface AnimeInfo {
            id?: string
            title?: string
            shortTitles?: Array<string>
            publicUrl?: string
            sequel?: string
            sex?: string
            twitterAccount?: string
            twitterHashTags?: Array<string>
            periodId?: string
        }
        export interface Period {
            id?: string
            year?: string
            season?: string
        }
        export interface GetAnimeInfoRequest {
            period?: Period
            limit?: number
            cursor?: string
        }
    }
}
```
API呼び出し用の関数を用意する。([AnimeInfoGapi.ts](https://github.com/kumo2ji/AnimeInfoClient/blob/master/AnimeInfoClientType/AnimeInfoGapi.ts))

```ts:AnimeInfoGapi.ts
namespace utils.AnimeInfoGapi {
    import Response = gapi.client.animeInfo.Response
    import AnimeInfo = gapi.client.animeInfo.AnimeInfo
    import Period = gapi.client.animeInfo.Period
    const ROOT = 'https://animeinfoserver.appspot.com/_ah/api'

    export function loadGapi(callback: () => void) {
        gapi.client.load('animeInfo', 'v1', callback, ROOT)
    }

    export function getAnime(callback: (resp: Response<AnimeInfo>) => void, period: Period = null) {
        gapi.client.animeInfo.get.anime({ period: period }).execute(callback)
    }
}
```

HTMLでは`https://apis.google.com/js/client.js?onload=init`をロードし、initを定義する。定義したinit関数がロード終了後呼ばれる。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8" />
    <meta name=viewport content="width=device-width, initial-scale=1">
    <title>Anime Info Client</title>
</head>
<body>
    <script src="AnimeInfoGapi.js"></script>
    <script src="app.js"></script>
    <script src="https://apis.google.com/js/client.js?onload=init"></script>
</body>
</html>
```

init関数では最初にgapi.client.loadを呼び出し、その後定義したアニメ情報APIを呼び出す。

```ts:app.ts
declare var init: Function
namespace app {
    export function init() {
        utils.AnimeInfoGapi.loadGapi(() => {
            utils.AnimeInfoGapi.getAnime((resp) => {
                var animeInfos = resp.items
            })
        })
    }
}
init = app.init
```