如何使用 Node.js SDK for Azure Mobile Apps

本文提供詳細資訊和範例,示範如何使用 Azure Mobile Apps 的 NodeJS 後端。

簡介

Azure Mobile Apps 提供將行動優化資料存取 Web API 新增至 Web 應用程式的功能。 Azure Mobile Apps SDK 適用于 ASP.NET Framework 和 Node.js Web 應用程式。 SDK 提供下列作業:

  • 資料存取的資料表作業(讀取、插入、更新、刪除)
  • 自訂 API 作業

這兩項作業都針對Azure App 服務允許的所有識別提供者提供驗證。 這些提供者包括社交識別提供者,例如 Facebook、Twitter、Google 和 Microsoft,以及適用于企業身分識別的 Microsoft Entra 識別碼。

支援的平台

Azure Mobile Apps Node.js SDK 支援 Node 6.x 和更新版本,且已測試至 Node 12.x。 其他版本的 Node 可能會運作,但不受支援。

Azure Mobile Apps Node.js SDK 支援兩個資料庫驅動程式:

  • node-mssql 驅動程式支援 Azure SQL 資料庫 和本機 SQL Server 實例。
  • sqlite3 驅動程式僅支援單一實例上的 SQLite 資料庫。

使用命令列建立基本節點後端

每個 Azure Mobile Apps Node.js 後端都會以 Express 應用程式的形式 啟動。 Express 是 Node.js 最受歡迎的 Web 服務架構。 您可以建立基本的 Express 應用程式,如下所示:

  1. 在命令或 PowerShell 視窗中,為您的專案建立目錄:

    $ mkdir basicapp
    
  2. 執行 npm init 以初始化封裝結構:

    $ cd basicapp
    $ npm init
    

    命令 npm init 會要求一組問題來初始化專案。 請參閱範例輸出:

    The npm init output

  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,以使用動態架構提供基礎 SQL 資料存放區未經驗證的存取權。 它適用于下列用戶端程式庫快速入門:

您可以在 GitHub 上的範例區域中找到此基本應用程式的 程式碼。

為您的應用程式啟用首頁

許多應用程式都是 Web 和行動應用程式的組合。 您可以使用 Express 架構來結合這兩個 Facet。 不過,有時候您可能只想實作行動介面。 提供首頁以確保 App Service 已啟動並執行很有用。 您可以提供自己的首頁或啟用暫時首頁。 若要啟用暫時首頁,請使用下列程式碼來具現化 Azure Mobile Apps:

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

如果您只想要在本機開發時可以使用這個選項,您可以將此設定新增至 azureMobile.js 組態檔:

module.exports = {
    homePage: true,
};

您可以視需要將其他設定新增至 azureMobile.js 檔案。

資料表作業

azure-mobile-apps Node.js Server SDK 提供機制,將儲存在 Azure SQL 資料庫的資料表公開為 Web API。 它提供五項作業:

作業 描述
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 的特定層面。

最佳做法是,您應該在目錄中的 JavaScript 檔案 tables 中定義每個資料表,然後使用 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 (布林值)。 您可以在資料表定義 JavaScript 檔案中定義資料表, tables 如下所示:

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() 方法來在啟動時建立資料庫架構。 方法 tables.initialize() 傳回承諾 ,讓 Web 服務在初始化資料庫之前不會提供要求。

使用 SQL Server Express 作為本機電腦上的開發資料存放區

Azure Mobile Apps Node.js SDK 提供三個選項來提供現用的資料:

  • 使用記憶體 驅動程式來提供非持續性的範例存放區。
  • 使用 mssql 驅動程式提供 SQL Server Express 資料存放區以供開發。
  • 使用 mssql 驅動程式提供 Azure SQL 資料庫資料存放區以供生產環境使用。

Azure Mobile Apps Node.js SDK 會使用 mssql Node.js 套件 來建立和使用 SQL Server Express 和 SQL 資料庫 的連線。 此套件會要求您在 SQL Server Express 實例上啟用 TCP 連線。

提示

記憶體驅動程式不提供一組完整的測試設施。 如果您想要在本機測試後端,建議您使用 SQL Server Express 資料存放區和 mssql 驅動程式。

  1. 下載並安裝 Microsoft SQL Server 2019 Developer

  2. 執行 Configuration Manager:

    • 展開樹狀功能表中的 [SQL Server 網路組態 ] 節點。
    • 選取 實例名稱 的 [ 通訊協定]。
    • 以滑鼠右鍵按一下 [ TCP/IP ],然後選取 [ 啟用 ]。 在快顯對話方塊中選取 [ 確定 ]。
    • 在樹狀目錄中選取 [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 入口網站 中的應用程式設定

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 入口網站都有對等的應用程式設定。 使用下列清單在應用程式設定設定您的應用程式:

應用程式設定 azureMobile.js 設定 描述 有效值
MS_MobileAppName NAME 應用程式的名稱 string
MS_MobileLoggingLevel logging.level 要記錄的訊息記錄層級下限 error, warning, info, verbose, debug, silly
MS_DebugMode 偵錯 啟用或停用偵錯模式 True、False
MS_TableSchema data.schema SQL 資料表的預設架構名稱 string (預設值:dbo)
MS_DynamicSchema data.dynamicSchema 啟用或停用偵錯模式 True、False
MS_DisableVersionHeader version (設定為未定義) 停用 X-ZUMO-Server-Version 標頭 True、False
MS_SkipVersionCheck skipversioncheck 停用用戶端 API 版本檢查 True、False

變更大部分的應用程式設定需要重新啟動服務。

使用 Azure SQL 作為生產數據存放區

在所有 Azure App 服務 應用程式類型中,使用 Azure SQL 資料庫 作為資料存放區完全相同。 如果您尚未這麼做,請遵循下列步驟來建立 Azure App 服務 後端。 建立 Azure SQL 實例,然後將應用程式設定SQLCONNSTR_MS_TableConnectionString設為您想要使用的 Azure SQL 實例 連接字串。 請確定執行後端的 Azure App 服務 可以與您的 Azure SQL 實例通訊。

需要驗證才能存取數據表

如果您想要搭配tables端點使用 App Service 驗證,您必須先在 Azure 入口網站 中設定 App Service 驗證。 如需詳細資訊,請參閱您想要使用之識別提供者的設定指南:

每個數據表都有一個存取屬性,可用來控制數據表的存取權。 下列範例顯示具有必要驗證的靜態定義數據表。

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 屬性可以接受三個值之一:

  • anonymous 表示允許用戶端應用程式讀取未經驗證的數據。
  • authenticated 表示用戶端應用程式必須使用要求傳送有效的驗證令牌。
  • disabled 表示此數據表目前已停用。

如果未定義存取屬性,則允許未經驗證的存取。

搭配數據表使用驗證宣告

您可以設定設定驗證時要求的各種宣告。 這些宣告通常無法透過 context.user 物件取得。 不過,您可以使用 方法來擷取它們 context.user.getIdentity() 。 方法會 getIdentity() 傳回解析為 對象的承諾。 物件是以驗證方法(facebook、、、twittermicrosoftaccountgoogle 或 ) aad為索引鍵。

注意

如果透過 Microsoft Entra ID 使用 Microsoft 驗證,則驗證方法為 aad,而不是 microsoftaccount

例如,如果您設定 Microsoft Entra 驗證並要求電子郵件位址宣告,您可以使用下表控制器將電子郵件位址新增至記錄:

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;

若要查看可用的宣告,請使用網頁瀏覽器來檢視 /.auth/me 網站的端點。

停用特定數據表作業的存取

除了出現在數據表上之外,存取屬性還可以用來控制個別作業。 有四個作業:

  • 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;

調整與數據表作業搭配使用的查詢

數據表作業的常見需求是提供數據的限制檢視。 例如,您可以提供以已驗證的使用者標識碼標記的數據表,以便您只能讀取或更新自己的記錄。 下表定義提供這項功能:

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 查詢屬性。 查詢屬性是 QueryJS 物件,用來將 OData 查詢轉換成數據後端可以處理的專案。 對於簡單的相等案例(如上述案例),您可以使用地圖。 您也可以新增特定的 SQL 子句:

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

在數據表上設定虛刪除

虛刪除實際上不會刪除記錄。 相反地,它會將已刪除的數據行設定為 true,將其標示為在資料庫中刪除。 除非行動用戶端 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:// oursite.azurewebsites.net/swagger。 您可以透過 /swagger/ui 端點存取 Swagger UI。 如果您選擇在整個應用程式中要求驗證,Swagger 會產生錯誤。 為了獲得最佳結果,請選擇在 Azure App 服務 驗證/授權設定中允許未經驗證的要求,然後使用 屬性控制驗證table.access

如果您只想要 Swagger 支援在本機開發,您也可以將 Swagger 選項新增至檔案 azureMobile.js

自訂 API

除了透過 /tables 端點的數據存取 API 之外,Azure Mobile Apps 還可以提供自定義 API 涵蓋範圍。 自定義 API 的定義方式與資料表定義類似,而且可以存取所有相同的設施,包括驗證。

定義自定義 API

自訂 API 的定義方式與資料表 API 大致相同:

  1. 建立 api 目錄。
  2. api 目錄中建立 API 定義 JavaScript 檔案。
  3. 使用 import 方法匯入 api 目錄。

以下是以我們稍早使用的基本應用程式範例為基礎的原型 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 會以與端點和自定義 API 相同的方式 tables 實作驗證。 若要將驗證新增至上一 access 節中開發的 API,請新增 屬性:

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;

用於端點的 tables 相同令牌必須用於需要驗證的自定義 API。

處理大型檔案上傳

Azure Mobile Apps SDK 會使用 本文剖析器中間件 ,在您的提交中接受和譯碼本文內容。 您可以預先設定本文剖析器,以接受較大的檔案上傳:

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 服務 為 Node.js 應用程式提供數種偵錯和疑難解答技術。 若要開始針對 Node.js Azure Mobile Apps 後端進行疑難解答,請參閱下列文章:

Node.js 應用程式可以存取各種診斷記錄工具。 在內部,Azure Mobile Apps Node.js SDK 會使用 [Winston] 進行診斷記錄。 當您啟用偵錯模式或將MS_DebugMode應用程式設定設為 true 時,會自動啟用記錄 Azure 入口網站。 產生的記錄會出現在 Azure 入口網站 的診斷記錄中。