かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

Azure Mobile AppsでUWPを作ってみよう「カスタムAPI編」

過去記事

あらすじ

Xamarinに寄り道しましたがUWPに戻ってきました。

APIを使おう

Azure Mobile Appsは、テーブルに簡単にアクセスする以外に、ちょっと複雑なことをさせたいと思った場合に備えてカスタムAPIを用意することもできるようになっています。

API機能を有効化するには、app.tsに以下のように書きます。

import * as express from 'express';
import * as azureMobileApps from 'azure-mobile-apps';

let app = express();
let mobile = azureMobileApps();

// init table
mobile.tables.import('./tables');
// init api
mobile.api.import('./api');
mobile.tables.initialize()
    .then(() => {
        app.use(<any>mobile);
        app.listen(process.env.PORT || 3000);
    });

こうすることで、apiフォルダに作ったjsファイルが自動でAPIとして登録されます。

日付を返すAPI

ということで、手始めに日付を返すAPIを作ってみようと思います。

import * as express from 'express';
import * as azureMobileApps from 'azure-mobile-apps';

let api: Azure.MobileApps.ApiDefinition = {
    get(req: express.Request, res: express.Response, next: express.NextFunction) {
        res.json({ currentDate: new Date() });
    },
};

module.exports = api;

上記のようにApiDefinitionを定義します。そしてmodule.exportすることで使えるようになります。 apiには、get, post, put, deleteが定義できます。それぞれHTTPのメソッドに対応しています。

引数は、リクエストとレスポンスと、次への処理へ繋げる関数になります。

レスポンスのjsonにオブジェクトを渡すことでJSON形式で返すことが出来ます。ローカルで実行してhttp://localhost:3000/api/dateにアクセスすると以下のように日付がJSONで取得できます。

f:id:okazuki:20160912192043p:plain

SQLの結果を返す

SQLを発行して結果を返すこともできます。

sqlparametersというプロパティを持ったオブジェクトをまず作成します。sqlには名前のとおりクエリを、parametersにはnamevalueプロパティを持ったオブジェクトの配列を渡すことでSQL内のパラメータを指定します。例えば、TODOITEMテーブルのtextの部分一致検索をする場合は以下のようになります。

import * as express from 'express';
import * as azureMobileApps from 'azure-mobile-apps';

function makeWhere(keyword: string): string {
    if (!keyword) { return ''; }
    return `WHERE TEXT LIKE '%' + @keyword + '%'`;
};


let api: Azure.MobileApps.ApiDefinition = {
    get(req: express.Request, res: express.Response, next: express.NextFunction) {
        let keyword = req.query.keyword;
        let query = {
            sql: `
                SELECT
                    *
                FROM
                    TODOITEM
                ${makeWhere(keyword)}`,
            parameters: [{ name: 'keyword', value: keyword }]
        };
        (<any>req.azureMobile.data).execute(query)
            .then(result => {
                res.json(result); 
            })
            .catch(error =>  {
                res.sendStatus(500); 
            });
    },
};

module.exports = api;

余談

このパラメータの指定方法ですが、公式ドキュメントが間違えててはまりました。

azure.microsoft.com

UWPからAPIの呼び出し

ただのREST APIになるのでHttpClientから呼んでもいいですが、MobileServiceClientにもAPI呼び出し機能があります。こっちを使うのがMobile Appsを使う場合は安パイでしょう。

以下のようにInvokeApiAsyncを呼び出すことが出来ます。API名、HTTPのメソッド、パラメータになります。

var results = await this.Client.InvokeApiAsync<TodoItem[]>(
    "todoitem", 
    HttpMethod.Get, 
    new Dictionary<string, string> { { "keyword", this.TextBoxInput.Text } });
this.ListViewTodos.ItemsSource = results;

実行すると以下のようになります。指定したキーワードのやつが取れてきてることが確認できます。

f:id:okazuki:20160912200411p:plain