Condividi tramite


Connettere le applicazioni all'API Fabric per GraphQL

Per connettere un'applicazione a un'API per GraphQL, sono necessarie tre informazioni importanti: un ID client, l'ID tenant e l'indirizzo dell'endpoint GraphQL in Fabric. Nelle sezioni seguenti viene illustrato come creare e recuperare tutti i dettagli necessari e come accedere all'API utilizzando un'applicazione di esempio.

Prerequisiti

  • Attualmente l'API per GraphQL richiede che le applicazioni utilizzino Microsoft Entra per l'autenticazione. L'applicazione deve essere opportunamente registrata e configurata per eseguire chiamate API su Fabric. Per altre informazioni, si veda Creare un'app Microsoft Entra in Azure.

  • L'utente autenticato che chiama l'API richiede autorizzazioni di esecuzione per l'API GraphQL (opzione Esegui query e mutazioni quando si aggiungono autorizzazioni di accesso diretto) e, se si usa il Single Sign-On (SSO) come opzione di connettività nell'API, sono necessarie autorizzazioni di lettura o scrittura nell'origine dati scelta di conseguenza. Per altre informazioni, vedere Connetti a un'origine dati e crea lo schema.

  • Prima di connettere un'applicazione, è necessario disporre di un'API per GraphQL in Fabric. Per altre informazioni, si veda Creare un'API per GraphQL in Fabric e aggiungere dati.

Creare un'app Microsoft Entra

Nei passaggi seguenti viene illustrato come configurare il supporto per un'applicazione ReactJS in Microsoft Entra.

  1. Registrare un'applicazione usando i passaggi descritti in Avvio rapido: Registrare un'applicazione con Microsoft Identity Platform.
  2. I valori dell'ID applicazione (client) e dell'ID directory (tenant) dell'app Microsoft Entra vengono visualizzati nella casella Riepilogo. Registrare questi valori perché sono necessari in seguito.
  3. Nell'elenco Gestisci selezionare autorizzazioni API , quindi Aggiungi autorizzazione.
  4. Aggiungere il servizio PowerBI, selezionare Autorizzazioni delegate e selezionare Autorizzazioni Item.Execute.All . Assicurarsi che il consenso dell'amministratore non sia obbligatorio.
  5. Tornare all'elenco Gestisci, selezionare , > a pagina singola.
  6. Ai fini dello sviluppo locale, aggiungere http://localhost:3000 in URI di reindirizzamento e verificare che l'applicazione sia abilitata per il flusso del codice di autorizzazione con la chiave di prova per Lo scambio di codice (PKCE). Selezionare il pulsante Configura per salvare le modifiche. Nel caso in cui l'applicazione riceva un errore correlato alle richieste tra le origini, aggiungere la piattaforma Applicazioni per dispositivi mobili e desktop nel passaggio precedente con lo stesso URI di reindirizzamento.
  7. Tornare a Authentication, scorrere verso il basso fino a Advanced Settings e, in Consenti flussi client pubblici, selezionare per Abilitare i flussi per dispositivi mobili e desktop seguenti.

Impostare un'API GraphQL di esempio per l'accesso all'applicazione

In questo esempio viene creata un'API GraphQL per esporre i dati di esempio Lakehouse ai client.

  1. Nella home page del portale di Infrastruttura selezionare Ingegneria dei dati dall'elenco dei carichi di lavoro.

  2. Nell'esperienza di Ingegneria dei dati, selezionare Usa un campione e in Lakehouse selezionare Festività pubbliche per creare automaticamente un nuovo Lakehouse con i dati delle festività pubbliche.

    Screenshot della selezione dell'opzione data Lakehouse di esempio.

  3. Seguendo la procedura descritta in Creare un'API per GraphQL, creare una nuova API GraphQL e selezionare il lakehouse creato. Aggiungere la tabella delle festività pubbliche per consentire ai client di accedere a questi dati.

    Screenshot dell'aggiunta del Lakehouse di esempio come origine dati GraphQL.

  4. Testare l'API GraphQL nell'editor API utilizzando la seguente query di esempio. È la stessa query utilizzata nell'applicazione client 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
         }
       }
     }
    
  5. Selezionare Copia endpoint sulla barra degli strumenti dell'elemento API.

    Screenshot delle opzioni della barra degli strumenti per un elemento API.

  6. Nella schermata Copia collegamento selezionare Copia.

    Screenshot della finestra di dialogo Copia collegamento, che mostra dove selezionare l'opzione Copia.

  7. Come ID client e ID tenant dell'app Microsoft Entra registrata in precedenza, copiare l'URI dell'endpoint come richiesto in un secondo momento.

Configurare un'app React per accedere all'API delle festività pubbliche

  1. Come punto di partenza viene utilizzata un'applicazione React esistente. Seguire tutti i passaggi dell'esercitazione Creare un'applicazione a pagina singola React e prepararla per l'autenticazione per creare un progetto React con l'autenticazione di Microsoft Entra già configurata, inclusi file e cartelle aggiuntivi da aggiungere alla struttura del progetto. È sufficiente modificare tre file per adattare l'app per il caso d'uso GraphQL.

  2. Nella cartella src aprire il file authConfig.js e sostituire il contenuto del file con il seguente frammento di codice:

     /*
      * 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",
     };
    

    Come si può vedere nel codice qui sopra, per accedere all'applicazione è importante utilizzare l'ambito corretto. In questo caso https://analysis.windows.net/powerbi/api/Item.Execute.All.

    Importante

    Gli ambiti potrebbero cambiare durante l'anteprima dell'API Microsoft Fabric per GraphQL.

  3. Sostituire i valori seguenti con i valori dell'interfaccia di amministrazione di Microsoft Entra.

    • clientId - L'identificatore dell'applicazione, detto anche client. Sostituire Enter_the_Application_Id_Here con il valore ID applicazione (client) registrato in precedenza dalla pagina di panoramica dell'applicazione Microsoft Entra registrata.
    • authority - Questo è composto da due parti:
      • L' Istanza è l'endpoint del provider di servizi cloud. Verificare i diversi endpoint disponibili in Cloud nazionali.
      • L' ID tenant è l'identificatore del tenant dove è registrata l'applicazione. Sostituire Enter_the_Tenant_Info_Here con il valore ID directory (tenant) registrato in precedenza nella pagina di panoramica dell'applicazione registrata.
    • graphQLEndpoint - API Fabric per l'endpoint GraphQL. Sostituire Enter_the_GraphQL_Endpoint_Here con l'endpoint API di GraphQL registrato in precedenza.
  4. Salvare il file.

  5. Nella stessa cartella src, aprire il file aApp.js e sostituire il contenuto del file con il seguente frammento di codice:

     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>
       );
     }
    
  6. Salvare il file.

  7. Infine, nella cartella src/componenti aprire il file ProfileData.jsx e sostituire il contenuto del file con il seguente frammento di codice:

     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>
     )};
    
  8. Salvare tutte le modifiche ai file.

  9. Nell'applicazione terminale preferita andare alla cartella radice del progetto React ed eseguire il comando npm start per testare l'applicazione in locale.

  10. Una volta caricata l'applicazione nel browser da http://localhost:3000, seguire la procedura descritta nell'ultima parte dell'esercitazione Chiamare l'API dall'applicazione per l'autenticazione.

  11. Dopo aver eseguito l'accesso, fare clic sul pulsante API di query in Fabric per i dati GraphQL.

    Screenshot dell'app React di esempio dopo l'accesso.

  12. Una richiesta autenticata con successo per l'API GraphQL in Fabric mostra i dati dalla query GraphQL a Lakehouse nell'applicazione client React:

    Screenshot dell'app React di esempio dopo aver ricevuto la richiesta GraphQL.

Usare un’entità servizio

Anche se i passaggi della sezione precedente sono necessari per fornire l'accesso alle entità utente, è anche possibile accedere all'API GraphQL con un'entità servizio:

  1. Seguire la procedura descritta nella sezione precedente per creare una seconda app Microsoft Entra con autorizzazioni simili (ambito Item.Execute.All per il servizio PowerBI). Nella nuova app aggiungere un segreto client in Certificati e segreti. Per altre informazioni, vedere Registrare un'app Microsoft Entra e creare un'entità servizio.

  2. Assicurarsi che gli amministratori tenant abbia abilitato l'utilizzo delle entità servizio in Fabric. Nel portale di amministrazione tenant passare a Impostazioni tenant. In Impostazioni sviluppatore abilitare le entità servizio può usare le API di infrastruttura. Con questa impostazione abilitata, l'applicazione sarà visibile nel portale di Infrastruttura per l'assegnazione di ruoli o autorizzazioni. Altre informazioni sul supporto delle identità sono disponibili.

  3. L'entità servizio dovrà accedere sia all'API GraphQL che all'origine dati, in particolare l'autorizzazione Execute per l'API GraphQL e l'accesso in lettura o scrittura richiesto nell'origine dati di scelta di conseguenza. Nel portale di infrastruttura aprire l'area di lavoro e selezionare i puntini di sospensione accanto all'API. Selezionare Gestisci autorizzazioni per l'API e quindi Aggiungi utente. Aggiungere l'applicazione e selezionare Esegui query e mutazioni, che fornirà le autorizzazioni Di esecuzione necessarie all'entità servizio. Ai fini dei test, il modo più semplice per implementare le autorizzazioni necessarie per l'API e l'origine dati consiste nell'aggiungere l'applicazione come membro dell'area di lavoro con un ruolo di collaboratore in cui si trovano sia l'API GraphQL che gli elementi dell'origine dati.

    Screenshot delle autorizzazioni dell'API GraphQL.

Importante

Quando si definisce l'opzione di connettività per l'API, assicurarsi che l'API sia configurata per l'uso dell'accesso Single Sign-On (SSO). Attualmente le entità servizio non supportano le credenziali salvate. Per altre informazioni, vedere Creare un'API per GraphQL in Fabric e aggiungere dati

Poiché un'entità servizio richiede un certificato o un segreto client, non è supportata da Microsoft Authentication Library (MSAL) in applicazioni a pagina singola come l'app React creata nell'ultimo passaggio. È possibile sfruttare un servizio back-end protetto correttamente con una logica di autorizzazione ben definita a seconda dei requisiti e dei casi d'uso.

Dopo aver configurato l'API per l'accesso da un'entità servizio, è possibile testarla in locale usando una semplice applicazione Node.JS nel computer locale:

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);
    }
}

Dopo aver installato le dipendenze (@azure/identity) con la gestione pacchetti Node.JS scelta, modificando il file con le informazioni necessarie, salvandolo ed eseguendolo (node <filename.js>), sarà possibile recuperare un token da Microsoft Entra.

Il token può quindi essere usato per richiamare l'API GraphQL usando PowerShell sostituendo i dettagli appropriati con il token appena recuperato, la query GraphQL che si vuole eseguire e l'endpoint dell'API GraphQL:

$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 


In alternativa, è possibile usare cURL per ottenere lo stesso risultato:

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)>"}'

A scopo di test locali, il codice Node.JS può essere leggermente modificato con una dipendenza aggiuntiva (axios) per recuperare il token e richiamare l'API in una singola esecuzione:

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();

Altri linguaggi

Cercare C#, Python e altri esempi di linguaggio per la connessione all'API GraphQL nel repository GitHub degli esempi di Microsoft Fabric.