読者です 読者をやめる 読者になる 読者になる

かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

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