若要将应用程序连接到适用于 GraphQL 的 API,需要三个关键详细信息: 客户端 ID、 租户 ID 和 Fabric 中的 GraphQL 终结点地址 。 以下部分介绍如何使用示例 React 应用程序创建和检索所需的详细信息并访问 API。
其他语言
本教程介绍如何将 React 示例应用程序连接到 Fabric API for GraphQL。 可以在 Microsoft Fabric 示例 GitHub 存储库中找到 C#、Python 和其他语言示例。
先决条件
在连接应用程序之前,请确保在 Fabric 中使用 GraphQL 的 API。 有关详细信息,请参阅在 Fabric 中创建 GraphQL API 并添加数据。
GraphQL 的 API 要求应用程序使用 Microsoft Entra 进行身份验证。 注册并配置应用程序以对 Fabric 执行 API 调用。 有关详细信息,请参阅在 Azure 中创建 Microsoft Entra 应用。
调用 API 的经过身份验证的凭据(用户主体、服务主体或托管标识)需要对 GraphQL API 执行权限(添加直接访问权限时运行查询和突变选项)。 如果使用单一登录(SSO)作为 API 中的连接选项,请确保凭据在所选数据源中具有读取或写入权限。 有关详细信息,请参阅连接到数据源并构建架构。
创建 Microsoft Entra 应用
以下步骤说明如何在 Microsoft Entra 中配置 ReactJS 应用程序的支持。
使用快速入门:使用 Microsoft 标识平台注册应用程序中所述的步骤注册应用程序。
Microsoft Entra 应用 应用程序(客户端)ID 和 目录(租户)ID 值显示在“摘要”框中。 记录这些值,因为稍后需要这些值。
在“管理”列表下,选择“API 权限”,然后选择“添加权限”。
添加 PowerBI 服务,选择 委派权限,然后选择 GraphQLApi.Execute.All 权限。 确认不需要管理员同意。
返回到 “管理 ”列表,选择“ 身份验证>添加平台>单页应用程序”。
出于本地开发目的,请在“重定向 URI”下添加
http://localhost:3000,并确认应用程序是否已启用具有代码交换证明密钥 (PKCE) 的授权代码流。 选择“配置”按钮以保存所做更改。 如果应用程序遇到与跨源请求相关的错误,请使用相同的重定向 URI 在上一步中添加 移动和桌面应用程序 平台。返回到“授权”,向下滚动到“高级设置”,然后在“允许公共客户端流”下,对“启用以下移动和桌面流”选择“是”。
为应用程序访问设置示例 GraphQL API
在本例中,我们创建了一个 GraphQL API 来向客户端公开示例湖屋数据。
在 Fabric 门户主页中,从工作负荷列表中选择“数据工程”。
在数据工程体验中,选择“ 使用示例”,然后在 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 应用中的 客户端 ID 和 租户 ID ,并复制终结点 URI,因为稍后需要它。
配置 React 应用以访问公共节假日 API
注释
如果想要跳过以下手动步骤,可以使用完整的应用程序克隆 GitHub 存储库 。 按照步骤 3,将从 Microsoft Entra 检索到的 GraphQL 终结点和 ID 的特定详细信息添加到文件 authConfig.js 中,使用 npm install 安装依赖项,然后跳到步骤 9 继续测试应用程序执行。
使用现有的 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: * [OpenID Connect scopes](/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes) */ export const loginRequest = { scopes: ["https://analysis.windows.net/powerbi/api/GraphQLApi.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/GraphQLApi.Execute.All。将以下值替换为 Microsoft Entra 管理中心的值。
clientId - 应用程序的标识符,也称为客户端。 替换为
Enter_the_Application_Id_Here之前从已注册的 Microsoft Entra 应用程序的概述页中记录的 Application(client) ID 值。authority - 这由两个部分组成:
“实例”是云提供程序的终结点。 在“国家云”查看可用的不同终结点。
“租户 ID”是在其中注册应用程序的租户的标识符。 用之前从已注册应用程序的概述页记录的
Enter_the_Tenant_Info_Here值替换 。
graphQLEndpoint - GraphQL 终结点的构造 API。 将
Enter_the_GraphQL_Endpoint_Here替换为前面记录的 GraphQL API 终结点。
保存文件。
在同一
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>CountryOrRegion</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 数据的 Query Fabric API 按钮。
对 Fabric 中 GraphQL API 的成功身份验证请求会将 GraphQL 查询中的数据返回到 React 客户端应用程序中的 Lakehouse: