將應用程式連線至適用於 GraphQL 的 Fabric API
注意
適用於 GraphQL 的 Microsoft Fabric API 目前為預覽版。
若要將應用程式連線到適用於 GraphQL 的 API,您需要三個重要資訊:用戶端 ID、租用戶 ID,以及 Fabric 中的 GraphQL 端點位址。 在下列各節中,我們將示範如何建立和擷取您需要的所有詳細資料,以及如何使用範例應用程式存取 API。
必要條件
目前適用於 GraphQL 的 API 要求應用程式使用 Microsoft Entra 進行驗證。 您的應用程式必須經過適當註冊和設定,才能針對 Fabric 執行 API 呼叫。 如需詳細資訊,請參閱在 Azure 中建立 Microsoft Entra 應用程式。
呼叫 API 的已驗證使用者需要 GraphQL API 的執行權限(在新增直接存取權限時的運行查詢和變更選項),而且,如果在 API 中使用單一登入(SSO)作為連線選項,則需根據所選的資料來源取得讀取或寫入權限。 如需詳細資訊,請參閱 連線至資料源並建置架構。
線上應用程式之前,您必須在 Fabric 中擁有適用於 GraphQL 的 API。 如需詳細資訊,請參閱在 Fabric 中建立適用於 GraphQL 的 API 並新增資料。
建立 Microsoft Entra 應用程式
在下列步驟中,我們會示範如何在 Microsoft entra 中設定 ReactJS 應用程式的支援。
- 使用 快速入門中所述的步驟註冊應用程式:使用 Microsoft 身分識別平台註冊應用程式,。
- Microsoft Entra 應用程式應用程式 (用戶端) ID 和 目錄 (租用戶) ID 值會顯示在 [摘要] 方塊中。 記錄這些值,因為稍後需要這些值。
- 在 [管理] 列表中,選取 [API 許可權],然後選取 [新增許可權]。
- 新增 PowerBI 服務、選取 [委派的許可權],然後選取 [Item.Execute.All] 許可權。 請確定不需要系統管理員同意。
- 回到 [管理] 列表,選取 [驗證>][新增平臺]、>[單頁應用程式]。
- 針對本機開發目的,請在 [重新導向 URI
http://localhost:3000
新增 ,並確認應用程式已針對授權碼流程啟用,且具有適用於程式代碼交換的證明金鑰 (PKCE) 。 選取 [設定] 按鈕來儲存變更。 如果應用程式收到與跨原始來源要求相關的錯誤,請使用相同的重新導向 URI,在上一個步驟中新增行動應用程式和傳統型應用程式平台。 - 回到 [驗證],向下捲動至 [進階設定],然後在 [允許公用用戶端流程] 下,選取 [[是][啟用下列行動和桌面流程]。
設定應用程式存取的範例 GraphQL API
在此範例中,我們會建立 GraphQL API,將範例 Lakehouse 資料公開給用戶端。
從 [網狀架構入口網站] 首頁,從工作負載清單中選取 [資料工程師]。
在資料工程體驗中,選取 [使用範例],然後在 [Lakehouse] 底下選取 [公共假日],以自動建立具有公共假日資料的新 Lakehouse。
遵循建立適用於 GraphQL 的 API 的步驟,建立新的 GraphQL API,然後選取您建立的 Lakehouse。 新增公共假日資料表,讓用戶端存取此資料。
使用下列範例查詢,在 API 編輯器中測試 GraphQL API。 這是我們在 React 使用者端應用程式中使用的相同查詢:
query { publicholidays (filter: {countryRegionCode: {eq:"US"}, date: {gte: "2024-01-01T00:00:00.000Z", lte: "2024-12-31T00:00:00.000Z"}}) { items { countryOrRegion holidayName date } } }
選取 API 項目工具列上的 [複製端點]。
在 [複製連結] 畫面中,選取 [複製]。
從稍早記錄Microsoft Entra 應用程式的用戶端標識碼和租用戶標識碼,請複製端點 URI,以供稍後使用。
設定 React 應用程式以存取公共假日 API
我們使用現有的 React 應用程式作為起點。 遵循建立 React 單頁應用程式教學課程 中的所有步驟,並準備進行驗證 ,以建立已設定Microsoft Entra 驗證的 React 專案,包括新增至項目結構所需的其他檔案和資料夾。 我們只需要變更三個檔案,以針對 GraphQL 使用案例調整應用程式。
在 [src] 資料夾中,開啟 authConfig.js 檔案,並以下列程式碼片段取代檔案的內容:
/* * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ import { LogLevel } from "@azure/msal-browser"; /** * Configuration object to be passed to MSAL instance on creation. * For a full list of MSAL.js configuration parameters, visit: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md */ export const graphqlConfig = { graphqlEndpoint: "`Enter_the_GraphQL_Endpoint_Here" }; export const msalConfig = { auth: { clientId: "Enter_the_Application_Id_Here", authority: "https://login.microsoftonline.com/Enter_the_Tenant_Info_Here", redirectUri: "http://localhost:3000", }, cache: { cacheLocation: "sessionStorage", // This configures where your cache will be stored storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge }, system: { loggerOptions: { loggerCallback: (level, message, containsPii) => { if (containsPii) { return; } switch (level) { case LogLevel.Error: console.error(message); return; case LogLevel.Info: console.info(message); return; case LogLevel.Verbose: console.debug(message); return; case LogLevel.Warning: console.warn(message); return; default: return; } } } } }; /** * Scopes you add here will be prompted for user consent during sign-in. * By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request. * For more information about OIDC scopes, visit: * https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes */ export const loginRequest = { scopes: ["https://analysis.windows.net/powerbi/api/Item.Execute.All"] }; /** * Add here the scopes to request when obtaining an access token for MS Graph API. For more information, see: * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/resources-and-scopes.md */ export const graphConfig = { graphMeEndpoint: "https://graph.microsoft.com/v1.0/me", };
如您在上述程式碼中所見,請務必使用正確的範圍來存取應用程式。 在我們的案例中
https://analysis.windows.net/powerbi/api/Item.Execute.All
。重要
在適用於 GraphQL 的 Microsoft Fabric API 預覽期間,範圍可能會變更。
將下列值取代為來自 Microsoft Entra 系統管理中心的值。
-
clientId
- 應用程式的識別碼,也稱為用戶端。 將取代Enter_the_Application_Id_Here
為 先前從已註冊的 Microsoft Entra 應用程式概觀頁面記錄的應用程式 (client) 識別子 值。 -
authority
- 這是由兩個部分組成:- 執行個體是雲端提供者的端點。 在國家雲端中檢查不同的可用端點。
- 租用戶識別碼是註冊應用程式的租用戶識別碼。 將 Enter_the_Tenant_Info_Here 取代為先前從註冊應用程式的概觀頁面記錄的目錄 (租用戶) 識別碼值。
-
graphQLEndpoint
- 適用於 GraphQL 的 Fabric API 端點。 使用稍早記錄的 GraphQL API 端點取代Enter_the_GraphQL_Endpoint_Here
。
-
儲存檔案。
在同一個 [src] 資料夾中,開啟 App.js 檔案,並以下列程式碼片段取代檔案的內容:
import React, { useState } from 'react'; import { PageLayout } from './components/PageLayout'; import { loginRequest, graphqlConfig } from './authConfig'; import { ProfileData } from './components/ProfileData'; import { AuthenticatedTemplate, UnauthenticatedTemplate, useMsal } from '@azure/msal-react'; import './App.css'; import Button from 'react-bootstrap/Button'; import Spinner from 'react-bootstrap/Spinner'; /** * Renders information about the signed-in user or a button to retrieve data about the user */ const ProfileContent = () => { const { instance, accounts } = useMsal(); const [graphqlData, setGraphqlData] = useState(null); const [display, setDisplay] = useState(false); function RequestGraphQL() { // Silently acquires an access token which is then attached to a request for GraphQL data instance .acquireTokenSilent({ ...loginRequest, account: accounts[0], }) .then((response) => { callGraphQL(response.accessToken).then((response) => setGraphqlData(response)); }); } async function callGraphQL(accessToken) { setDisplay(true); const query = `query { publicholidays (filter: {countryRegionCode: {eq:"US"}, date: {gte: "2024-01-01T00:00:00.000Z", lte: "2024-12-31T00:00:00.000Z"}}) { items { countryOrRegion holidayName date } } }`; fetch(graphqlConfig.graphqlEndpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${accessToken}`, }, body: JSON.stringify({ query: query }) }) .then((res) => res.json()) .then((result) => setGraphqlData(result)); } return ( <> <h5 className="card-title">Welcome {accounts[0].name}</h5> <br/> {graphqlData ? ( <ProfileData graphqlData={graphqlData} /> ) : ( <Button variant="primary" onClick={RequestGraphQL}> Query Fabric API for GraphQL Data {display ? ( <Spinner as="span" animation="border" size="sm" role="status" aria-hidden="true" /> ) : null} </Button> )} </> ); }; /** * If a user is authenticated the ProfileContent component above is rendered. Otherwise a message indicating a user is not authenticated is rendered. */ const MainContent = () => { return ( <div className="App"> <AuthenticatedTemplate> <ProfileContent /> </AuthenticatedTemplate> <UnauthenticatedTemplate> <h5> <center> Please sign-in to see your profile information. </center> </h5> </UnauthenticatedTemplate> </div> ); }; export default function App() { return ( <PageLayout> <center> <MainContent /> </center> </PageLayout> ); }
儲存檔案。
最後,在 src/components 資料夾下,開啟 ProfileData.jsx 檔案,並以下列程式碼片段取代檔案內容:
import React from "react"; import ListGroup from 'react-bootstrap/ListGroup'; import Table from 'react-bootstrap/Table'; /** * Renders information about the user obtained from MS Graph * @param props */ export const ProfileData = (props) => { const holidays = props.graphqlData.data.publicholidays.items; return ( <Table striped bordered hover responsive> <thead> <tr> <th>Country</th> <th>Holiday</th> <th>Date</th> </tr> </thead> <tbody> {holidays.map((item,i) => ( <tr key={i}> <td>{item.countryOrRegion}</td> <td>{item.holidayName}</td> <td>{item.date}</td> </tr> ))} </tbody> </Table> )};
儲存所有檔案變更。
在您選擇的終端應用程式中,移至 React 專案的根資料夾,然後執行命令
npm start
以在本機測試應用程式。從瀏覽器中載入
http://localhost:3000
應用程式之後,請遵循教學課程最後部分中的步驟,從應用程式 呼叫 API 以進行驗證。登入之後,按下 [查詢適用於 GraphQL 的 Fabric API 資料] 按鈕。
Fabric 中 GraphQL API 的成功驗證要求會將 GraphQL 查詢中的資料傳回至 React 用戶端應用程式中的 Lakehouse:
使用服務主體
雖然上一節中的步驟需要提供用戶主體的存取權,但也可以使用服務主體存取 GraphQL API:
請遵循上一節中的步驟,建立具有類似許可權的第二個Microsoft Entra 應用程式(PowerBI Service 的 Item.Execute.All 範圍)。 在新應用程式中,在 [憑證和秘密] 底下新增客戶端密碼,如需詳細資訊,請參閱註冊 Microsoft Entra 應用程式並建立服務主體。
請確定租用戶系統管理員已啟用 Fabric 中的服務主體使用方式。 在租使用者管理入口網站中,移至 [ 租用戶設定]。 在 [開發人員設定] 底下,啟用服務主體可以使用網狀架構 API。 啟用此設定後,應用程式會顯示在網狀架構入口網站中,以取得角色或許可權指派。 您可以找到身 分識別支持的詳細資訊。
服務主體需要存取 GraphQL API 和數據源,更具體來說 ,對 GraphQL API 執行 許可權,以及據以選擇之數據源所需的讀取或寫入許可權。 在網狀架構入口網站中,開啟工作區,然後選取 API 旁邊的省略號。 選取 [ 管理 API 的許可權 ],然後 選取 [新增使用者]。 新增應用程式,然後選取 [ 執行查詢和突變],以提供服務主體所需的 執行 許可權。 為了進行測試,實作 API 和數據源所需許可權的最簡單方式,就是將應用程式新增為具有 GraphQL API 和數據源專案所在參與者角色的工作區成員。
重要
定義 API 的連線選項時,請確定 API 已設定為使用單一登錄 (SSO)。 目前服務主體不支援已儲存的認證。 如需詳細資訊,請參閱 在 Fabric 中建立 GraphQL 的 API 並新增數據
由於服務主體需要憑證或客戶端密碼,因此在單頁應用程式中的 Microsoft 驗證連結庫 (MSAL) 不支援它,例如我們在最後一個步驟中建置的 React 應用程式。 您可以根據您的需求和使用案例,利用妥善定義的授權邏輯適當保護後端服務。
一旦您的 API 設定為由服務主體存取,您就可以在本機使用簡單的Node.JS應用程式在本機測試它:
const { ClientSecretCredential } = require('@azure/identity');
// Define your Microsoft Entra ID credentials
const tenantId = "<YOUR_TENANT_ID>";
const clientId = "<YOUR_CLIENT_ID>";
const clientSecret = "<YOUR_CLIENT_SECRET>"; // Service principal secret value
const scope = "https://api.fabric.microsoft.com/.default"; // The scope of the token to access Fabric
// Create a credential object with service principal details
const credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
// Function to retrieve the token
async function getToken() {
try {
// Get the token for the specified scope
const tokenResponse = await credential.getToken(scope);
console.log("Access Token:", tokenResponse.token);
} catch (err) {
console.error("Error retrieving token:", err.message);
}
}
使用您選擇的Node.JS套件管理員安裝相依性 (@azure/identity
) 之後,使用所需的資訊修改檔案,儲存並執行它 (node <filename.js>
), 您將可以從 entra Microsoft 擷取權杖。
然後,您可以使用 PowerShell 來叫用 GraphQL API,方法是將適當的詳細數據取代為您 剛才擷取的令牌 、 您想要執行的 GraphQL 查詢 ,以及 GraphQL API 端點:
$headers = @{
Authorization = "Bearer <YOUR_TOKEN>"
'Content-Type' = 'application/json'
}
$body = @{
query = @"
<YOUR_GRAPHQL_QUERY>
"@
}
# Make the POST request to the GraphQL API
$response = Invoke-RestMethod -Uri "<YOUR_GRAPHQL_API_ENDPOINT>" -Method POST -Headers $headers -Body ($body | ConvertTo-Json)
# Output the response
$response | ConvertTo-Json -Depth 10
或者,您可以使用 cURL 來達成相同的結果:
curl -X POST <YOUR_GRAPHQL_API_ENDPOINT> \
-H "Authorization: <YOUR_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"query": "<YOUR_GRAPHQL_QUERY(in a single line)>"}'
為了進行本機測試,Node.JS程式代碼可以稍微修改,並搭配額外的相依性 (axios
) 來擷取令牌,並在單一執行中叫用 API:
const { ClientSecretCredential } = require('@azure/identity');
const axios = require('axios');
// Microsoft Entra ID credentials
const tenantId = "<YOUR_TENANT_ID>";
const clientId = "<YOUR_CLIENT_ID>";
const clientSecret = "<YOUR_CLIENT_SECRET>"; // Service principal secret value
// GraphQL API details
const graphqlApiUrl = "YOUR_GRAPHQL_API_ENDPOINT>";
const scope = "https://api.fabric.microsoft.com/.default"; // The scope to request the token for
// The GraphQL query
const graphqlQuery = {
query: `
<YOUR_GRAPHQL_QUERY>
`
};
// Function to retrieve a token and call the GraphQL API
async function fetchGraphQLData() {
try {
// Step 1: Retrieve token using the ClientSecretCredential
const credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
const tokenResponse = await credential.getToken(scope);
const accessToken = tokenResponse.token;
console.log("Access token retrieved!");
// Step 2: Use the token to make a POST request to the GraphQL API
const response = await axios.post(
graphqlApiUrl,
graphqlQuery,
{
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
}
}
);
// Step 3: Output the GraphQL response data
console.log("GraphQL API response:", JSON.stringify(response.data));
} catch (err) {
console.error("Error:", err.message);
}
}
// Execute the function
fetchGraphQLData();
其他語言
在 Microsoft Fabric 範例 GitHub 存放庫中尋找 C#、Python 和其他語言範例,以連線至 GraphQL API。