實作 Microsoft Fabric 後端
此 Microsoft Fabric 工作負載開發範例存放庫 是建置需要與各種服務整合的應用程式,以及與 Lakehouse 架構整合的起點。 本文可協助您設定環境,並設定必要的元件以開始使用。 本文概述架構中的重要元件及其角色。
前端
前端是您管理使用者體驗 (UX) 和行為的位置。 它會透過 iFrame 與 Fabric 前端入口網站通訊,以利順暢的互動。
如需詳細資訊,請參閱 Microsoft Fabric 工作負載開發工具包前端。
後端
後端會同時儲存資料和中繼資料。 它會使用建立、讀取、更新和刪除 (CRUD) 作業來建立工作負載專案和元數據,並執行作業來填入記憶體中的數據。 前端與後端之間的通訊是透過公用 API 建立的。
Azure 轉送和 DevGateway
Azure 轉播可讓您在開發人員模式中,在本機開發環境和網狀架構後端之間進行通訊。 在開發人員模式中,工作負載在開發人員的電腦上運作。
DevGateway 公用程式有兩個角色:
- 它負責處理工作負載的 Azure 中繼通道面向,並在特定工作區的上下文中使用 Fabric 管理工作負載本地實例的註冊。 公用程式會在通道中斷連線時處理取消註冊。
- 其可與 Azure 轉譯搭配運作,以將工作負載 API 呼叫從 Fabric 傳送至工作負載。
工作負載控制 API 呼叫會直接從工作負載對 Fabric 進行。 呼叫不需要 Azure 轉接通道。
Lakehouse 整合
工作負載開發工具組架構可順暢地與 Lakehouse 架構整合,以進行儲存、讀取和擷取數據等作業。 互動可透過 Azure 轉寄和網狀架構 SDK 來協助確保安全且已驗證的通訊。 如需詳細資訊,請參閱 使用客戶數據。
驗證和安全性
Microsoft Entra ID 用於安全驗證,確保架構內的所有互動都獲得授權且安全。
開發 工具包概觀 提供我們架構的一瞥。 如需如何設定專案、進行驗證指導方針及開始使用的詳細資訊,請參閱下列文章:
前端會透過 iFrame 與 Fabric 前端入口網站建立通訊。 入口網站接著會呼叫其公開的公用 API,來與網狀架構後端互動。
針對後端開發方塊與 Fabric 後端之間的互動,Azure 轉送會作為管道。 此外,後端開發方塊會與 Lakehouse 緊密整合。 使用安裝在後端開發方塊上的 Azure 轉送和 Fabric 軟體開發套件 (SDK) 來促進通訊。
透過 Microsoft Entra 確保這些元件內所有通訊的驗證。 Microsoft Entra 為前端、後端、Azure 轉播、網狀架構 SDK 和 Lakehouse 之間的互動提供安全且已驗證的環境。
必要條件
- .NET 7.0 SDK
- Visual Studio 2022
確定 NuGet 套件管理員已整合到 Visual Studio 安裝中。 需要此工具,才能簡化對我們的專案必要的外部媒體櫃和套件的管理。
NuGet 套件管理
<NuspecFile>Packages\manifest\ManifestPackageDebug.nuspec</NuspecFile>
和<NuspecFile>Packages\manifest\ManifestPackageRelease.nuspec</NuspecFile>
:這些屬性指定用於在偵錯和發行模式下建立 NuGet 套件的 NuSpec 檔案的路徑。 NuSpec 檔案包含套件的相關中繼資料,例如其 ID、版本、相依性和其他相關信息。<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
:當設定為true
時,這個屬性會指示建置程式在每個組建期間自動產生NuGet 套件。 這個屬性有助於確保套件一律應用最新的專案變更。<IsPackable>true</IsPackable>
:當設定為true
時,這個屬性表示專案可以封裝到 NuGet 套件中。 可封裝是用於建置程式期間產生 NuGet 套件之專案的基本屬性。
針對偵錯模式產生的 NuGet 套件位於 建置程式之後的 src\bin\Debug 目錄中。
當您在雲端模式中工作時,可以將Visual Studio組建組態變更為 [發行 ] 並建置您的套件。 產生的套件位於 src\bin\Release
目錄中。 如需詳細資訊,請參閱 在雲端模式中工作指南。
相依性
後端重複使用範例取決於下列 Azure SDK 套件:
- Azure.Core
- Azure.Identity
- Azure.Storage.Files.DataLake
- Microsoft 身分識別套件
若要設定 NuGet 封裝管理員,請在開始建置程式之前,先在 [套件來源] 區段中指定路徑。
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<BuildDependsOn>PreBuild</BuildDependsOn>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<IsPackable>true</IsPackable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<NuspecFile>Packages\manifest\ManifestPackageRelease.nuspec</NuspecFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<NuspecFile>Packages\manifest\ManifestPackageDebug.nuspec</NuspecFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.Core" Version="1.38.0" />
<PackageReference Include="Azure.Identity" Version="1.11.0" />
<PackageReference Include="Azure.Storage.Files.DataLake" Version="12.14.0" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.9" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.5" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="7.0.0" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.60.3" />
<PackageReference Include="Microsoft.IdentityModel.Protocols" Version="6.30.1" />
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="6.30.1" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.30.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\ServiceDependencies\" />
</ItemGroup>
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="powershell.exe -ExecutionPolicy Bypass -File ValidationScripts\RemoveErrorFile.ps1 -outputDirectory ValidationScripts\" />
<Exec Command="powershell.exe -ExecutionPolicy Bypass -File ValidationScripts\ManifestValidator.ps1 -inputDirectory .\Packages\manifest\ -inputXml WorkloadManifest.xml -inputXsd WorkloadDefinition.xsd -outputDirectory ValidationScripts\" />
<Exec Command="powershell.exe -ExecutionPolicy Bypass -File ValidationScripts\ItemManifestValidator.ps1 -inputDirectory .\Packages\manifest\ -inputXsd ItemDefinition.xsd -outputDirectory ValidationScripts\" />
<Exec Command="powershell.exe -ExecutionPolicy Bypass -File ValidationScripts\ValidateNoDefaults.ps1 -outputDirectory ValidationScripts\" />
<Error Condition="Exists('ValidationScripts\ValidationErrors.txt')" Text="Validation errors with either manifests or default values" File="ValidationScripts\ValidationErrors.txt" />
</Target>
</Project>
開始使用
若要在本機電腦上設定工作負載範例專案:
複製存放庫:執行
git clone https://github.com/microsoft/Microsoft-Fabric-workload-development-sample.git
。在 Visual Studio 2022 中,開啟方案。
依照驗證教學課程中的指示來設定應用程式註冊。 請確定前端和後端專案都有本文所述的必要設定。 Microsoft Entra 用於安全驗證,以協助確保架構內的所有互動都獲得授權且安全。
更新 Microsoft OneLake DFS 基底 URL。 視您的網狀架構環境而定,您可能可以在 src\Constants 資料夾中更新 的值
OneLakeDFSBaseURL
。 預設值為onelake.dfs.fabric.microsoft.com
,但您可以更新 URL 以反映您的環境。 如需 DFS 路徑的詳細資訊,請參閱 OneLake 檔。設定工作負載組態。
- 將workload-dev-mode.json從 src/Config複製到 C:。
- 在workload-dev-mode.json檔案中,更新下列欄位以符合您的組態:
-
WorkspaceGuid:您的工作區標識符。 當您在 Fabric 中選取工作區時,可以在瀏覽器 URL 中找到此值。 例如:
https://app.powerbi.com/groups/<WorkspaceID>/
。 - ManifestPackageFilePath:資訊清單套件的位置。 當您建置方案時,它會將指令清單套件儲存在 src\bin\Debug 中。 本文稍後會提供指令清單套件的詳細資訊。
- WorkloadEndpointURL:工作負載端點 URL。
-
WorkspaceGuid:您的工作區標識符。 當您在 Fabric 中選取工作區時,可以在瀏覽器 URL 中找到此值。 例如:
- 在 Packages/manifest/WorkloadManifest.xml 檔案中,更新下列欄位以符合您的設定:
-
<AppId>
:工作負載的用戶端標識碼(應用程式標識符)Microsoft Entra 應用程式。 -
<RedirectUri>
:重新導向 URI。 您可以在您在 [驗證] 底下建立的應用程式註冊中找到此值。 -
<ResourceId>
:傳入Microsoft Entra 令牌的物件。 您可以在您建立的應用程式註冊中,於 [公開 API] 底下找到此資訊。
-
- 在 src/appsettings.json 檔案中,更新下列欄位以符合您的設定:
- PublisherTenantId:工作負載發行者租用戶的 ID。
- ClientId:工作負載的用戶端標識碼(應用程式標識符)Microsoft Entra 應用程式。
- ClientSecret:工作負載 Microsoft Entra 應用程式的密碼。
- 對象:傳入Microsoft Entra 令牌的物件。 您可以在您建立的應用程式註冊中,於 [公開 API] 底下找到此資訊。 這個設定也稱為 應用程式識別碼 URI。
產生資訊清單套件。
若要產生指令清單套件檔案,請建 置Fabric_Extension_BE_Boilerplate。 組建是產生指令清單套件檔案的三個步驟程式。 它會執行下列步驟:
- 在 Packages\manifest/ 中WorkloadManifest.xml觸發 ManifestValidator.ps1,並在 Packages\manifest/中的所有專案 XMLs 上觸發 ItemManifestValidator.ps1 Item1.xml。。 如果驗證失敗,就會產生錯誤檔案。 您可以在 ValidationScripts/中檢視驗證腳本。
- 如果錯誤檔案存在,組建會失敗,並出現錯誤 :指令清單或預設值的驗證錯誤。 若要查看 Visual Studio 中的錯誤檔案,請在驗證結果中按兩下錯誤。
- 驗證成功之後,請將 WorkloadManifest.xml 和 Item1.xml 檔案封裝到 ManifestPackage.1.0.0.nupkg。 產生的套件可在 src\bin\Debug 中找到。
將 ManifestPackage.1.0.0.nupkg 檔案複製到workload-dev-mode.json組態檔中定義的路徑。
Program.cs 是應用程式的進入點和啟動指令。 在此檔案中,您可以設定各種服務、初始化應用程式以及啟動 Web 主機。
建置以確保您的專案可以存取編譯和執行所需的相依性。
從 Microsoft 下載中心下載
執行 Microsoft.Fabric.Workload.DevGateway.exe 應用程式,並使用在
WorkspaceGuid
的使用者登入。驗證之後,外部工作負載會透過 Azure 轉送與 Fabric 後端建立通訊。 此程式牽涉到由指定 Proxy 節點所促進的轉接註冊和通訊管理。 包含工作負載指令清單的套件會上傳併發佈。
在這個階段,Fabric 會偵測工作負載,並納入其配置的容量。
您可以監視控制台中的潛在錯誤。
如果未顯示任何錯誤,則會建立連線、成功執行註冊,並有系統地上傳工作負載指令清單。
在 Visual Studio 中,將啟動專案變更為 [未定案] 專案,然後選取 [ 執行]。
使用重複使用範例專案
程式碼產生
我們使用工作負載重複使用 C# ASP.NET Core 範例來示範如何使用 REST API 建置工作負載。 此範例會從根據工作負載 API Swagger 規格產生伺服器存根和合約類別開始。 您可以使用數個 Swagger 程式代碼產生工具中的任何一個來產生程式代碼。 重複使用範例會使用 NSwag。 此範例包含 命令行腳本GenerateServerStub.cmd ,其會包裝NSwag程式代碼產生器。 該指令採用單一參數,即 NSwag 安裝目錄的完整路徑。 它也會檢查資料夾中的 Swagger 定義檔 (swagger.json) 和組態檔 (nswag.json)。
執行此文稿會產生名為 WorkloadAPI_Generated.cs 的 C# 檔案。 此檔案的內容可以邏輯分割成三個部分,如下幾節所述。
ASP.NET Core Stub 控制器
ItemLifecycleController
和 JobsController
類別是工作負載 API 兩個子集之核心控制器的精簡實作 ASP.NET:專案生命週期管理和作業。 這些類別會插入 ASP.NET Core HTTP 管線。 它們可作為 Swagger 規格中定義之 API 方法的進入點。 類別會將呼叫轉送至工作負載所提供的「實際」實作。
以下是 方法的 CreateItem
範例:
/// <summary>
/// Called by Microsoft Fabric for creating a new item.
/// </summary>
/// <remarks>
/// Upon item creation Fabric performs some basic validations, creates the item with 'provisioning' state and calls this API to notify the workload. The workload is expected to perform required validations, store the item metadata, allocate required resources, and update the Fabric item metadata cache with item relations and ETag. To learn more see [Microsoft Fabric item update flow](https://updateflow).
/// <br/>
/// <br/>This API should accept [SubjectAndApp authentication](https://subjectandappauthentication).
/// <br/>
/// <br/>##Permissions
/// <br/>Permissions are checked by Microsoft Fabric.
/// </remarks>
/// <param name="workspaceId">The workspace ID.</param>
/// <param name="itemType">The item type.</param>
/// <param name="itemId">The item ID.</param>
/// <param name="createItemRequest">The item creation request.</param>
/// <returns>Successfully created.</returns>
[Microsoft.AspNetCore.Mvc.HttpPost, Microsoft.AspNetCore.Mvc.Route("workspaces/{workspaceId}/items/{itemType}/{itemId}")]
public System.Threading.Tasks.Task CreateItem(System.Guid workspaceId, string itemType, System.Guid itemId, [Microsoft.AspNetCore.Mvc.FromBody] CreateItemRequest createItemRequest)
{
return _implementation.CreateItemAsync(workspaceId, itemType, itemId, createItemRequest);
}
工作負載實作的介面
IItemLifecycleController
和 IJobsController
是先前提及之「實際」實作的介面。 它們會定義控制器實作的相同方法。
合約類別的定義
C# 合約類別是 API 所使用的類別。
實作
產生程式代碼之後的下一個步驟是實作 IItemLifecycleController
和 IJobsController
介面。 在重複使用範例中, ItemLifecycleControllerImpl
並 JobsControllerImpl
實作這些介面。
例如,此程式代碼是 CreateItem API 的實作:
/// <inheritdoc/>
public async Task CreateItemAsync(Guid workspaceId, string itemType, Guid itemId, CreateItemRequest createItemRequest)
{
var authorizationContext = await _authenticationService.AuthenticateControlPlaneCall(_httpContextAccessor.HttpContext);
var item = _itemFactory.CreateItem(itemType, authorizationContext);
await item.Create(workspaceId, itemId, createItemRequest);
}
處理項目承載
數個 API 方法接受不同類型的「承載」做為要求主體的一部分,或傳回承載作為回應的一部分。 例如, CreateItemRequest
具有 creationPayload
屬性。
"CreateItemRequest": {
"description": "Create item request content.",
"type": "object",
"additionalProperties": false,
"required": [ "displayName" ],
"properties": {
"displayName": {
"description": "The item display name.",
"type": "string",
"readOnly": false
},
"description": {
"description": "The item description.",
"type": "string",
"readOnly": false
},
"creationPayload": {
"description": "Creation payload specific to the workload and item type, passed by the item editor or as Fabric Automation API parameter.",
"$ref": "#/definitions/CreateItemPayload",
"readOnly": false
}
}
}
這些承載屬性的類型定義於 Swagger 規格中。 每種承載都具有專用類型。 這些類型不會定義任何特定屬性,而且允許包含任何屬性。
以下是類型的範例 CreateItemPayload
:
"CreateItemPayload": {
"description": "Creation payload specific to the workload and item type.",
"type": "object",
"additionalProperties": true
}
產生的 C# 合約類別定義為 partial
。 它們具有已定義屬性的字典。
以下是範例:
/// <summary>
/// Creation payload specific to the workload and item type.
/// </summary>
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.20.0.0 (NJsonSchema v10.9.0.0 (Newtonsoft.Json v13.0.0.0))")]
public partial class CreateItemPayload
{
private System.Collections.Generic.IDictionary<string, object> _additionalProperties;
[Newtonsoft.Json.JsonExtensionData]
public System.Collections.Generic.IDictionary<string, object> AdditionalProperties
{
get { return _additionalProperties ?? (_additionalProperties = new System.Collections.Generic.Dictionary<string, object>()); }
set { _additionalProperties = value; }
}
}
程式代碼可以使用這個字典來讀取和傳回屬性。 不過,更好的方法是使用對應的類型和名稱來定義特定屬性。 您可以在 partial
產生的類別上使用 宣告,以有效率地定義屬性。
例如, CreateItemPayload.cs 檔案包含 類別的 CreateItemPayload
互補定義。
在這裡範例中,定義會新增 Item1Metadata
屬性:
namespace Fabric_Extension_BE_Boilerplate.Contracts.FabricAPI.Workload
{
/// <summary>
/// Extend the generated class by adding item-type-specific fields.
/// In this sample every type will have a dedicated property. Alternatively, polymorphic serialization could be used.
/// </summary>
public partial class CreateItemPayload
{
[Newtonsoft.Json.JsonProperty("item1Metadata", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public Item1Metadata Item1Metadata { get; init; }
}
}
不過,如果工作負載支援多個專案類型,類別 CreateItemPayload
必須能夠在每個項目類型一個處理不同類型的建立承載。 您有兩個選項。 重複使用範例中使用的更簡單方式是定義多個選擇性屬性,每個屬性都代表不同項目類型的建立承載。 然後,每個要求只有一組屬性,根據所建立的項目類型。 或者,您可以實作多型串行化,但這個選項不會在範例中示範,因為選項不會提供任何重大優點。
例如,若要支援兩個專案類型,類別定義必須擴充,如下列範例所示:
namespace Fabric_Extension_BE_Boilerplate.Contracts.FabricAPI.Workload
{
public partial class CreateItemPayload
{
[Newtonsoft.Json.JsonProperty("item1Metadata", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public Item1Metadata Item1Metadata { get; init; }
[Newtonsoft.Json.JsonProperty("item2Metadata", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public Item2Metadata Item2Metadata { get; init; }
}
}
注意
傳送至工作負載的承載是由用戶端所產生。 它可以是專案編輯器 iFrame 或網狀架構自動化 REST API。 用戶端負責傳送正確的承載,並比對項目類型。 工作負載負責驗證。 Fabric 會將此承載視為不透明物件,並且只會將其從用戶端傳輸到工作負載。 同樣地,對於工作負載傳回給客戶端的承載,工作負載和客戶端必須負責正確處理承載。
例如,此程式代碼示範樣板範例 item1 實作如何處理承載:
protected override void SetDefinition(CreateItemPayload payload)
{
if (payload == null)
{
Logger.LogInformation("No payload is provided for {0}, objectId={1}", ItemType, ItemObjectId);
_metadata = Item1Metadata.Default.Clone();
return;
}
if (payload.Item1Metadata == null)
{
throw new InvalidItemPayloadException(ItemType, ItemObjectId);
}
if (payload.Item1Metadata.Lakehouse == null)
{
throw new InvalidItemPayloadException(ItemType, ItemObjectId)
.WithDetail(ErrorCodes.ItemPayload.MissingLakehouseReference, "Missing Lakehouse reference");
}
_metadata = payload.Item1Metadata.Clone();
}
疑難排解和偵錯
下一節說明如何針對部署進行疑難解答和偵錯。
已知問題和解決方式
取得已知問題的相關信息和解決方式。
遺失客戶端密碼
錯誤:
Microsoft.Identity.Client.MsalServiceException:設定問題正在防止驗證。 請查看來自伺服器的錯誤訊息,以取得詳細資料。 您可以在應用程式註冊入口網站中修改設定。 如需詳細資訊,請參閱 https://aka.ms/msal-net-invalid-client
。
原始例外狀況:AADSTS7000215:已提供無效的客戶端密碼。 請確定要求中傳送的秘密是客戶端密碼值,而不是新增至應用程式 app_guid
設定之秘密的用戶端密碼識別碼。
解決方案:請確定您已在 appsettings.json中定義正確的客戶端密碼。
建立項目期間發生錯誤,因為缺少管理員同意
錯誤:
Microsoft.Identity.Client.MsalUiRequiredException: AADSTS65001:使用者或系統管理員未同意使用標識符 <example ID>
為 的應用程式。 請傳送此使用者和資源的互動式授權要求。
解決方法:
在專案編輯器中,移至痛苦的底部,然後選取 [瀏覽至驗證頁面]。
在 [範圍] 下,輸入 .default,然後選取 [取得存取令牌]。
在對話框中,核准修訂。
因為容量選取,所以項目建立失敗
錯誤:
PriorityPlacement:沒有核心服務可用於優先順序放置。 只有 name
、 guid
和 workload-name
可用。
解決方法:
身為使用者,您可能只能存取試用版容量。 請確定您使用具有存取權的容量。
檔案建立失敗,發生 404 (NotFound) 錯誤
錯誤:
為 filePath 建立新檔案失敗:『workspace-id』/'lakehouse-id'/Files/data.json。 回應狀態代碼未指出成功: 404 (NotFound)。
解決方法:
請確定您使用的是符合您環境的 OneLake DFS URL。 例如,如果您使用 PPE 環境,請在 EnvironmentConstants.OneLakeDFSBaseUrl
變更為適當的 URL。
偵錯
當您針對各種作業進行疑難解答時,可以在程式代碼中設定斷點來分析和偵錯行為。 請依照下列步驟進行有效的偵錯:
- 在您的開發環境中開啟程式碼。
- 移至相關的作業處理程式函式(例如,
OnCreateFabricItemAsync
針對 CRUD 作業或控制器中的端點進行execute
作業)。 - 將中斷點放在您想要檢查程序碼的特定行。
- 在偵錯模式中執行應用程式。
- 從您要偵錯的前端觸發作業。
調試程式會在指定的斷點暫停執行,以便您可以檢查變數、逐步執行程式代碼,以及找出問題。
工作區
如果您是將後端連線到範例工作負載專案,您的專案必須屬於與容量相關聯的工作區。 根據預設, [我的工作區] 工作區 不會與容量相關聯。 否則,您可能會收到下列螢幕快照中顯示的錯誤:
切換至具名工作區。 保留預設工作區名稱 [我的工作區]。
從正確的工作區載入範例工作負載,然後繼續進行測試:
參與
我們歡迎對這個專案的貢獻。 如果您發現任何問題或想要新增功能,請依照以下步驟進行:
- 派生存放庫。
- 為您的功能或錯誤修復建立新的分支。
- 進行您的變更,然後認可這些變更。
- 將變更推送至您的存放庫。
- 建立具有變更清楚描述的提取要求。