Azure Mobile Apps 向け Node.js SDK の使用方法

この記事では、Azure Mobile Apps 向けの Node.js バックエンドを使用する方法についての詳細な情報と例を提供します。

はじめに

Azure Mobile Apps では、Web アプリケーションにモバイルに最適化されたデータ アクセス Web API を追加する機能が提供されます。 Azure Mobile Apps SDK は、ASP.NET Framework と Node.js の Web アプリケーション向けに用意されています。 この SDK を使用すると、次の処理を実行できます。

  • データ アクセスのためのテーブル操作 (読み取り、挿入、更新、削除)
  • カスタム API 操作

どちらの操作も、Azure App Service が許可するすべての ID プロバイダーに認証を提供します。 これらのプロバイダーには、Facebook、Twitter、Google、Microsoft などのソーシャル ID プロバイダー、およびエンタープライズ ID のための Azure Active Directory などがあります。

サポートされているプラットフォーム

Azure Mobile Apps Node.js SDK では、Node 6.x 以降がサポートされており、Node 12.x までのテストが行われています。 Node の他のバージョンが動作する場合もありますが、サポートされているわけではありません。

Azure Mobile Apps Node.js SDK では、次の 2 つのデータベース ドライバーがサポートされています。

  • node-mssql ドライバーは、Azure SQL Database とローカルの SQL Server インスタンスをサポートしています。
  • sqlite3 ドライバーは、単一のインスタンスでのみ、SQLite データベースをサポートします。

コマンド ラインを使用して基本的な Node バックエンドを作成する

Azure Mobile Apps Node.js バックエンドはすべて Express アプリケーションとして開始されます。 Express は、Node.js で使用可能な最も人気のある Web サービス フレームワークです。 次のように、基本的な Express アプリケーションを作成できます。

  1. コマンド ウィンドウまたは PowerShell ウィンドウで、プロジェクトのディレクトリを作成します。

    $ mkdir basicapp
    
  2. npm init を実行して、パッケージの構造を初期化します。

    $ cd basicapp
    $ npm init
    

    npm init コマンドでは、プロジェクトを初期化するための一連の質問が示されます。 次の出力例を参照してください。

    npm init の出力

  3. npm リポジトリから express ライブラリと azure-mobile-apps ライブラリをインストールします。

    npm install --save express azure-mobile-apps
    
  4. app.js ファイルを作成して、基本的なモバイル サーバーを実装します。

    var express = require('express'),
        azureMobileApps = require('azure-mobile-apps');
    
    var app = express(),
        mobile = azureMobileApps();
    
    // Define a TodoItem table.
    mobile.tables.add('TodoItem');
    
    // Add the Mobile API so it is accessible as a Web API.
    app.use(mobile);
    
    // Start listening on HTTP.
    app.listen(process.env.PORT || 3000);
    

このアプリケーションは、単一のエンドポイント (/tables/TodoItem) でモバイルに最適化された Web API を作成します。この Web API は、動的スキーマを使用して基になる SQL データ ストアへの認証されていないアクセスを可能にします。 次のクライアント ライブラリのクイックスタートに従う場合に適しています。

この基本的なアプリケーションのコードは、GitHub のサンプル領域にあります。

アプリケーションのホーム ページを有効にする

多くのアプリケーションは、Web アプリとモバイル アプリの組み合わせです。 Express フレームワークを使用すると、2 つのファセットを結合することができます。 ただし、モバイル インターフェイスのみを実装する場合もあります。 アプリ サービスを確実に稼動させるために、ホーム ページを用意すると便利です。 ホーム ページを指定するか、一時的なホーム ページを有効にします。 一時的なホーム ページを有効にするには、次のコードを使用して Azure Mobile Apps をインスタンス化します。

var mobile = azureMobileApps({ homePage: true });

ローカルで開発するときにのみ、このオプションを使用できるようにする場合は、この設定を azureMobile.js 構成ファイルに追加できます。

module.exports = {
    homePage: true,
};

必要に応じて、他の設定を azureMobile.js ファイルに追加できます。

テーブルの操作

azure-mobile-apps Node.js Server SDK では、Web API として Azure SQL Database に格納されたデータ テーブルを公開するためのメカニズムが提供されます。 以下の 5 つの操作が提供されます。

操作 説明
GET /tables/tablename テーブルのすべてのレコードを取得します。
GET /tables/tablename/:id テーブルの特定のレコードを取得します。
POST /tables/tablename テーブルのレコードを作成します。
PATCH /tables/tablename/:id テーブルのレコードを更新します。
DELETE /tables/tablename/:id テーブルのレコードを削除します。

この Web API では OData v3 がサポートされており、テーブル スキーマを拡張してオフライン データ同期をサポートします。

動的スキーマを使用してテーブルを定義する

テーブルを使用する前に、テーブルを定義する必要があります。 静的スキーマで (スキーマ内の列を定義する場合)、または動的に (SDK が受信要求に基づいてスキーマを制御する場合) テーブルを定義できます。 さらに、定義に JavaScript コードを追加することで、Web API の特定の側面を制御できます。

ベスト プラクティスとして、tables ディレクトリ内の JavaScript ファイルに各テーブルを定義し、tables.import() メソッドを使用してテーブルをインポートする必要があります。 basic-app サンプルを拡張して、app.js ファイルを次のように調整します。

var express = require('express'),
    azureMobileApps = require('azure-mobile-apps');

var app = express(),
    mobile = azureMobileApps();

// Define the database schema that is exposed.
mobile.tables.import('./tables');

// Provide initialization of any tables that are statically defined.
mobile.tables.initialize().then(function () {
    // Add the Mobile API so it is accessible as a Web API.
    app.use(mobile);

    // Start listening on HTTP.
    app.listen(process.env.PORT || 3000);
});

次のように ./tables/TodoItem.js にテーブルを定義します。

var azureMobileApps = require('azure-mobile-apps');

var table = azureMobileApps.table();

// Additional configuration for the table goes here.

module.exports = table;

テーブルでは、既定で動的スキーマが使用されます。

静的スキーマを使用してテーブルを定義する

Web API を使用して公開する列を明示的に定義することができます。 azure-mobile-apps Node.js SDK では、オフライン データ同期に必要なその他の列が指定したリストに自動的に追加されます。 たとえば、クイックスタート クライアント アプリケーションには、text (文字列) と complete (ブール値) という 2 つの列を持つテーブルが必要になります。 このテーブルは、次のように、(tables ディレクトリにある) テーブル定義 JavaScript ファイルで定義できます。

var azureMobileApps = require('azure-mobile-apps');

var table = azureMobileApps.table();

// Define the columns within the table.
table.columns = {
    "text": "string",
    "complete": "boolean"
};

// Turn off the dynamic schema.
table.dynamicSchema = false;

module.exports = table;

静的にテーブルを定義する場合は、tables.initialize() メソッドを呼び出して起動時にデータベース スキーマを作成する必要もあります。 Web サービスがデータベースの初期化前に要求を処理しないように、tables.initialize() メソッドは promise を返します。

ローカル コンピューター上で開発データ ストアとして SQL Server Express を使用する

Azure Mobile Apps Node.js SDK には、すぐに利用できるデータを提供する 3 つのオプションが用意されています。

  • メモリ ドライバーを使用して、非永続ストアの例を提供します。
  • mssql ドライバーを使用して、開発用の SQL Server Express データ ストアを提供します。
  • mssql ドライバーを使用して、運用環境の Azure SQL Database データ ストアを提供します。

Azure Mobile Apps Node.js SDK では mssql Node.js パッケージを使って、SQL Server Express と SQL Database の両方への接続を確立および使用します。 このパッケージでは、SQL Server Express インスタンスで TCP 接続を有効にする必要があります。

ヒント

メモリ ドライバーでは、テスト用の完全な機能セットは提供されません。 ローカルでバックエンドをテストする場合は、SQL Server Express データ ストアと mssql ドライバーを使用することをお勧めします。

  1. Microsoft SQL Server 2019 Developer をダウンロードしてインストールします。

  2. Configuration Manager を実行します。

    • ツリー メニューの [SQL Server ネットワークの構成] ノードを展開します。
    • [ <インスタンス名> のプロトコル] を選択します。
    • [TCP/IP] を右クリックし、 [有効化] を選択します。 ポップアップ ダイアログ ボックスで [OK] を選択します。
    • ツリー メニューの [SQL Server のサービス] を選択します。
    • [SQL Server ( <インスタンス名> )] を右クリックし、 [再起動] を選択します。
    • Configuration Manager を閉じます。

Azure Mobile Apps でデータベースへの接続に使用できるユーザー名とパスワードを作成する必要もあります。 作成したユーザーに dbcreator サーバー ロールがあることを確認します。 ユーザーの構成の詳細については、SQL Server のドキュメントを参照してください

選択したユーザー名とパスワードは必ずメモしておきます。 データベース要件によっては、サーバー ロールまたはアクセス許可の割り当てがさらに必要になる場合があります。

Node.js アプリケーションは、SQLCONNSTR_MS_TableConnectionString 環境変数を読み取って、このデータベースの接続文字列を確認します。 ご使用の環境にこの変数を設定できます。 たとえば、PowerShell を使用して、以下のようにこの環境変数を設定することができます。

$env:SQLCONNSTR_MS_TableConnectionString = "Server=127.0.0.1; Database=mytestdatabase; User Id=azuremobile; Password=T3stPa55word;"

TCP/IP 接続を介してデータベースにアクセスします。 接続に使用するユーザー名とパスワードを入力します。

ローカル開発用のプロジェクトを構成する

Azure Mobile Apps では、ローカル ファイル システムから azureMobile.js という JavaScript ファイルを読み取ります。 運用環境の Azure Mobile Apps SDK の構成にはこのファイルを使用しないでください。 代わりに、Azure portal の [アプリ設定] を使用してください。

azureMobile.js ファイルでは構成オブジェクトをエクスポートする必要があります。 最も一般的な設定は次のとおりです。

  • データベース設定
  • 診断ログ設定
  • 代替 CORS 設定

前のデータベース設定を実装する azureMobile.js ファイルの例を次に示します。

module.exports = {
    cors: {
        origins: [ 'localhost' ]
    },
    data: {
        provider: 'mssql',
        server: '127.0.0.1',
        database: 'mytestdatabase',
        user: 'azuremobile',
        password: 'T3stPa55word'
    },
    logging: {
        level: 'verbose'
    }
};

パスワードがクラウドに格納されないように、azureMobile.js.gitignore ファイル (または他のソース コード管理の無視ファイル) に追加することをお勧めします。

モバイル アプリのアプリ設定を構成する

azureMobile.js ファイル内のほとんどの設定には、Azure portal に相当するアプリ設定があります。 次の一覧を参照して、 [アプリ設定] でアプリを構成してください。

アプリ設定 azureMobile.js setting 説明 有効な値
MS_MobileAppName name アプリの名前 string
MS_MobileLoggingLevel logging.level ログ記録するメッセージの最小ログ レベル error、warning、info、verbose、debug、silly
MS_DebugMode debug デバッグ モードを有効または無効にします true、false
MS_TableSchema data.schema SQL テーブルの既定のスキーマ名 string (既定: dbo)
MS_DynamicSchema data.dynamicSchema デバッグ モードを有効または無効にします true、false
MS_DisableVersionHeader version (undefined に設定) X-ZUMO-Server-Version ヘッダーの無効化 true、false
MS_SkipVersionCheck skipversioncheck クライアント API バージョン チェックの無効化 true、false

ほとんどのアプリ設定を変更した場合、サービスの再起動が必要になります。

Azure SQL を運用データ ストアとして使用する

Azure SQL Database をデータ ストアとして使用する方法は、Azure App Service アプリケーションのすべての種類で同じです。 Azure App Service バックエンドをまだ作成していない場合は、これらの手順に従って作成します。 Azure SQL インスタンスを作成してから、アプリ設定 SQLCONNSTR_MS_TableConnectionString を、使用する Azure SQL インスタンスの接続文字列に設定します。 バックエンドを実行している Azure App Service が Azure SQL インスタンスと通信できるようにします。

テーブルへのアクセスに認証を要求する

tables エンドポイントで App Service 認証を使用する場合は、まず Azure portal で App Service 認証を構成する必要があります。 詳細については、使用する ID プロバイダーの構成ガイドを参照してください。

各テーブルには、テーブルへのアクセスを制御するために使用できる access プロパティがあります。 次のサンプルでは、認証を必要とする静的に定義されたテーブルを示します。

var azureMobileApps = require('azure-mobile-apps');

var table = azureMobileApps.table();

// Define the columns within the table.
table.columns = {
    "text": "string",
    "complete": "boolean"
};

// Turn off the dynamic schema.
table.dynamicSchema = false;

// Require authentication to access the table.
table.access = 'authenticated';

module.exports = table;

access プロパティには、次の 3 つの値を使用できます。

  • anonymous は、認証なしでデータを読み取る許可をクライアント アプリケーションに与えることを示します。
  • authenticated は、クライアント アプリケーションが要求で有効な認証トークンを送信する必要があることを示します。
  • disabled は、このテーブルが現在無効になっていることを示します。

access プロパティが定義されていない場合は、非認証アクセスが許可されます。

テーブルで認証要求を使用する

認証が設定されている場合、要求されている各種要求を設定できます。 これらの要求は context.user オブジェクトでは通常使用できません。 ただし、context.user.getIdentity() メソッドを使用して取得できます。 getIdentity() メソッドは、オブジェクトに解決される promise を返します。 オブジェクトのキーは、認証方法 (facebookgoogletwittermicrosoftaccountaad) に設定されます。

注意

Azure Active Directory で Microsoft 認証を使用する場合、認証方法は microsoftaccount ではなく aad です。

たとえば、Azure Active Directory 認証を設定し、電子メール アドレス要求を行う場合は、次のテーブル コントローラーを使用してレコードに電子メール アドレスを追加できます。

var azureMobileApps = require('azure-mobile-apps');

// Create a new table definition.
var table = azureMobileApps.table();

table.columns = {
    "emailAddress": "string",
    "text": "string",
    "complete": "boolean"
};
table.dynamicSchema = false;
table.access = 'authenticated';

/**
* Limit the context query to those records with the authenticated user email address
* @param {Context} context the operation context
* @returns {Promise} context execution Promise
*/
function queryContextForEmail(context) {
    return context.user.getIdentity().then((data) => {
        context.query.where({ emailAddress: data.aad.claims.emailaddress });
        return context.execute();
    });
}

/**
* Adds the email address from the claims to the context item - used for
* insert operations
* @param {Context} context the operation context
* @returns {Promise} context execution Promise
*/
function addEmailToContext(context) {
    return context.user.getIdentity().then((data) => {
        context.item.emailAddress = data.aad.claims.emailaddress;
        return context.execute();
    });
}

// Configure specific code when the client does a request.
// READ: only return records that belong to the authenticated user.
table.read(queryContextForEmail);

// CREATE: add or overwrite the userId based on the authenticated user.
table.insert(addEmailToContext);

// UPDATE: only allow updating of records that belong to the authenticated user.
table.update(queryContextForEmail);

// DELETE: only allow deletion of records that belong to the authenticated user.
table.delete(queryContextForEmail);

module.exports = table;

どのような要求が使用できるかを確認するには、Web ブラウザーを使用し、サイトの /.auth/me エンドポイントを表示します。

特定のテーブル操作へのアクセスを無効にする

テーブルでの表示だけでなく、個々の操作を制御するために access プロパティを使用できます。 操作には以下の 4 つがあります。

  • read は、テーブルに対する RESTful GET 操作です。
  • insert は、テーブルに対する RESTful POST 操作です。
  • update は、テーブルに対する RESTful PATCH 操作です。
  • delete は、テーブルに対する RESTful DELETE 操作です。

たとえば、読み取り専用の認証されていないテーブルを指定できます。

var azureMobileApps = require('azure-mobile-apps');

var table = azureMobileApps.table();

// Read-only table. Only allow READ operations.
table.read.access = 'anonymous';
table.insert.access = 'disabled';
table.update.access = 'disabled';
table.delete.access = 'disabled';

module.exports = table;

テーブル操作で使用されるクエリを調整する

テーブル操作の一般的な要件は、データの制限付きビューを提供することです。 たとえば、ユーザーが独自のレコードの読み取りまたは更新のみを実行できるように、認証済みユーザー ID でタグ付けされているテーブルを提供できます。 次のテーブル定義では、この機能を提供しています。

var azureMobileApps = require('azure-mobile-apps');

var table = azureMobileApps.table();

// Define a static schema for the table.
table.columns = {
    "userId": "string",
    "text": "string",
    "complete": "boolean"
};
table.dynamicSchema = false;

// Require authentication for this table.
table.access = 'authenticated';

// Ensure that only records for the authenticated user are retrieved.
table.read(function (context) {
    context.query.where({ userId: context.user.id });
    return context.execute();
});

// When adding records, add or overwrite the userId with the authenticated user.
table.insert(function (context) {
    context.item.userId = context.user.id;
    return context.execute();
});

module.exports = table;

通常はクエリを実行する操作には、where 句で調整できる query プロパティがあります。 query プロパティは QueryJS オブジェクトであり、これを使用して、データ バックエンドで処理できるものに OData クエリを変換します。 (上記のような) 単純な等式の場合は、マップを使用できます。 また、特定の SQL 句を追加することもできます。

context.query.where('myfield eq ?', 'value');

テーブルの論理削除を構成する

論理削除では実際にレコードは削除されません。 代わりに、削除列を true に設定して、データベース内のレコードを削除済みとしてマークします。 Mobile Client SDK で includeDeleted() が使用されない限り、Azure Mobile Apps SDK によって結果から論理削除レコードが自動的に削除されます。 論理削除のテーブルを構成するには、テーブル定義ファイルで softDelete プロパティを設定します。

var azureMobileApps = require('azure-mobile-apps');

var table = azureMobileApps.table();

// Define the columns within the table.
table.columns = {
    "text": "string",
    "complete": "boolean"
};

// Turn off the dynamic schema.
table.dynamicSchema = false;

// Turn on soft delete.
table.softDelete = true;

// Require authentication to access the table.
table.access = 'authenticated';

module.exports = table;

クライアント アプリケーション、WebJob、Azure 関数、カスタム API など、レコードを完全に削除するためのメカニズムを確立します。

データベースに対するデータのシード処理を実行する

新しいアプリケーションを作成する場合、データでのテーブルのシード処理が必要になることがあります。 データのシード処理は、以下のようにテーブル定義 JavaScript ファイル内で行うことができます。

var azureMobileApps = require('azure-mobile-apps');

var table = azureMobileApps.table();

// Define the columns within the table.
table.columns = {
    "text": "string",
    "complete": "boolean"
};
table.seed = [
    { text: 'Example 1', complete: false },
    { text: 'Example 2', complete: true }
];

// Turn off the dynamic schema.
table.dynamicSchema = false;

// Require authentication to access the table.
table.access = 'authenticated';

module.exports = table;

データのシード処理は、Azure Mobile Apps SDK を使用してテーブルを作成した場合にのみ発生します。 データベースにテーブルが既に存在する場合、テーブルにデータは挿入されません。 動的スキーマが有効になっている場合、スキーマはシード処理されたデータから推論されます。

tables.initialize() メソッドを明示的に呼び出して、サービスの実行開始時にテーブルを作成することをお勧めします。

Swagger のサポートを有効にする

Azure Mobile Apps には、組み込みの Swagger のサポートが付属しています。 Swagger のサポートを有効にするには、最初に依存関係として swagger ui をインストールします。

npm install --save swagger-ui

その後、Azure Mobile Apps コンストラクターで Swagger のサポートを有効にすることができます。

var mobile = azureMobileApps({ swagger: true });

開発エディションでのみ Swagger サポートを有効にするには、 NODE_ENV アプリ設定を使用して、開発時に Swagger サポートを有効にできます。

var mobile = azureMobileApps({ swagger: process.env.NODE_ENV !== 'production' });

swagger エンドポイントは、http://自分のサイト.azurewebsites.net/swagger にあります。 Swagger UI には、 /swagger/ui エンドポイントからアクセスできます。 アプリケーション全体で認証を必要とする場合、エラーが生成されます。 最良の結果を得るには、Azure App Service の [認証/承認] 設定で認証されていない要求を許可し、table.access プロパティを使用して認証を制御します。

また、ローカルでの開発にのみ Swagger のサポートが必要な場合は、azureMobile.js ファイルに Swagger オプションを追加できます。

カスタム API

/tables エンドポイント経由のデータ アクセス API に加え、Azure Mobile Apps ではカスタム API も提供できます。 カスタム API はテーブル定義と同じような方法で定義され、認証を含む、すべての同じ機能にアクセスできます。

カスタム API を定義する

カスタム API は、テーブル API とほぼ同じ方法で定義されます。

  1. api ディレクトリを作成します。
  2. api ディレクトリに API 定義 JavaScript ファイルを作成します。
  3. import メソッドを使用して、api ディレクトリをインポートします。

前に使用した basic-app サンプルに基づくプロトタイプの API 定義を以下に示します。

var express = require('express'),
    azureMobileApps = require('azure-mobile-apps');

var app = express(),
    mobile = azureMobileApps();

// Import the custom API.
mobile.api.import('./api');

// Add the Mobile API so it is accessible as a Web API.
app.use(mobile);

// Start listening on HTTP
app.listen(process.env.PORT || 3000);

ここでは、Date.now() メソッドを使用してサーバーの日付を返す API の例を見てみましょう。 api/date.js ファイルを以下に示します。

var api = {
    get: function (req, res, next) {
        var date = { currentTime: Date.now() };
        res.status(200).type('application/json').send(date);
    });
};

module.exports = api;

各パラメーターは、標準的な RESTful 動詞 (GET、POST、PATCH または DELETE) のいずれかです。 メソッドは、必要な出力を送信する標準的な ExpressJS ミドルウェア関数です。

カスタム API へのアクセスに認証を要求する

Azure Mobile Apps SDK では、tables エンドポイントとカスタム API の両方に対して同じ方法で認証を実装します。 前のセクションで開発した API に認証を追加するには、access プロパティを追加します。

var api = {
    get: function (req, res, next) {
        var date = { currentTime: Date.now() };
        res.status(200).type('application/json').send(date);
    });
};
// All methods must be authenticated.
api.access = 'authenticated';

module.exports = api;

以下のように、特定の操作で認証を指定することもできます。

var api = {
    get: function (req, res, next) {
        var date = { currentTime: Date.now() };
        res.status(200).type('application/json').send(date);
    }
};
// The GET methods must be authenticated.
api.get.access = 'authenticated';

module.exports = api;

認証を必要とするカスタム API には、tables エンドポイントで使用されるものと同じトークンを使用する必要があります。

大きなファイルのアップロードを処理する

Azure Mobile Apps SDK では、body-parser ミドルウェアを使用して、送信された本文の内容を受け入れ、デコードします。 大きなファイルのアップロードを受け入れるように body-parser を事前構成できます。

var express = require('express'),
    bodyParser = require('body-parser'),
    azureMobileApps = require('azure-mobile-apps');

var app = express(),
    mobile = azureMobileApps();

// Set up large body content handling.
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));

// Import the custom API.
mobile.api.import('./api');

// Add the Mobile API so it is accessible as a Web API.
app.use(mobile);

// Start listening on HTTP.
app.listen(process.env.PORT || 3000);

ファイルは送信前に base 64 でエンコードされます。 このエンコードによって実際のアップロードのサイズは増加します (そのため、このサイズを考慮する必要があります)。

カスタム SQL ステートメントを実行する

Azure Mobile Apps SDK を使用すると、要求オブジェクトを介してコン​​テキスト全体にアクセスできます。 定義されたデータ プロバイダーに対して、パラメーター化された SQL ステートメントを簡単に実行できます。

var api = {
    get: function (request, response, next) {
        // Check for parameters. If not there, pass on to a later API call.
        if (typeof request.params.completed === 'undefined')
            return next();

        // Define the query. Anything that the mssql
        // driver can handle is allowed.
        var query = {
            sql: 'UPDATE TodoItem SET complete=@completed',
            parameters: [{
                completed: request.params.completed
            }]
        };

        // Execute the query. The context for Azure Mobile Apps is available through
        // request.azureMobile. The data object contains the configured data provider.
        request.azureMobile.data.execute(query)
        .then(function (results) {
            response.json(results);
        });
    }
};

api.get.access = 'authenticated';
module.exports = api;

デバッグ

Azure Mobile Apps をデバッグ、診断、およびトラブルシューティングする

Azure App Service では、Node.js アプリケーションに関するいくつかのデバッグとトラブルシューティングの手法が提供されます。 Node.js Azure Mobile Apps バックエンドのトラブルシューティングを開始する場合は、次の記事を参照してください。

Node.js アプリケーションは、広範囲の診断ログ ツールにアクセスできます。 Azure Mobile Apps Node.js SDK では、内部で診断ログに [Winston] を使用します。 デバッグ モードを有効にするか、Azure portal で MS_DebugMode アプリ設定を true に設定すると、ログは自動的に有効になります。 生成されたログは、Azure Portal の診断ログに表示されます。