Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Importante
Cette fonctionnalité est actuellement en préversion. Les conditions d’utilisation supplémentaires des préversions de Microsoft Azure incluent des conditions juridiques supplémentaires qui s’appliquent aux fonctionnalités Azure en version bêta, en préversion ou qui ne sont pas encore mises en disponibilité générale.
Dans ce tutoriel, apprenez à interagir par programmation avec Microsoft Purview à l’aide de l’API GraphQL. Pour plus d’informations sur GraphQL en général, consultez cette introduction à GraphQL.
L’utilisation de GraphQL est similaire à l’utilisation des API REST, car vous envoyez une charge utile JSON à un point de terminaison de service. Toutefois, GraphQL nous permet de retourner des informations complètes en une seule extraction, ce qui élimine le besoin de plusieurs appels d’API.
GraphQL utilise également la récupération déclarative des données. La récupération déclarative des données est utile pour l’extraction sélective sur des champs tels quel’entité liée auterme/ de classification/ liée à l’entité d’origine. En utilisant GraphQL avec ces modèles de requête, nous pouvons optimiser la récupération des bases de données back-end et la transmission des données. Un bon exemple est « Obtenir une entité avec des entités associées filtrées, séparées par des alias ».
Avec sa fonctionnalité d’introspection, l’API GraphQL devient auto-descriptive, ce qui permet aux clients de récupérer les détails du schéma, tels que les requêtes, les types et les paramètres de requête disponibles. En savoir plus sur l’introspection.
Configuration requise
Si vous n’avez pas d’abonnement Azure, créez un compte gratuit avant de commencer.
Vous devez disposer d’un compte Microsoft Purview existant. Si ce n’est pas le cas, consultez le guide de démarrage rapide pour la création d’un compte Microsoft Purview.
Pour établir un jeton du porteur et appeler des API, consultez la documentation sur l’authentification des API pour Microsoft Purview.
point de terminaison GraphQL
Pour toutes les demandes, vous pouvez envoyer une POST requête au point de terminaison suivant :
POST https://{{endpoint}}/datamap/api/graphql
- Si vous utilisez le nouveau portail Microsoft Purview, la valeur {{endpoint}} est :
api.purview-service.microsoft.com. - Si vous utilisez le portail de gouvernance Microsoft Purview classique, la valeur {{endpoint}} est :
{your_purview_account_name}.purview.azure.com.
Requête de base
Entité - Lister par GUID
query {
entities(where: { guid: ["<guid1>", "<guid2>"] }) { #Values in the array are combined as a logical-OR.
guid
createTime
updateTime
typeName
attributes
name
qualifiedName
description
}
}
Exemple de réponse :
{
"data": {
"entities": [
{
"guid": "9fb74c11-ac48-4650-95bc-760665c5bd92",
"createTime": 1553072455110,
"updateTime": 1553072455110,
"typeName": "azure_storage_account",
"attributes": {
"qualifiedName": "https://exampleaccount.core.windows.net",
"name": "ExampleStorageAccount",
},
"name": "ExampleStorageAccount",
"qualifiedName": "https://exampleaccount.core.windows.net",
"description": "Example Storage Account"
}
]
}
}
Interroger des entités par type et par nom qualifié
query {
entities(
where: {
type: { typeName: ["<entityType1>", "<entityType2>"] }
qualifiedName: { in: ["<qualifiedName1>", "<qualifiedName2>"] }
}
) {
guid
typeName
qualifiedName
attributes
}
}
L’opérateur in est utilisé pour interroger plusieurs noms qualifiés.
Les opérateurs possibles peuvent être exists|eq|ne|in|nin|gt|ge|lt|le. Vous trouverez plus de détails sur le schéma de serveur avec l’introspection.
Extraction de données déclaratives
Obtenir l’entité avec les champs sélectionnés
query {
entities(where: { guid: "<guid>" }) {
guid
typeName
attributes
businessAttributes
qualifiedName
}
}
Obtenir l’entité avec tous les champs
query {
entities(where: { guid: "<guid>" }) {
guid
createTime
createdBy
updateTime
updatedBy
lastModifiedTS
typeName
attributes
businessAttributes
collectionId
customAttributes
hierarchyInfo {
...hierarchyInfoFields
}
labels
sensitivityLabel {
...sensitivityLabelFields
}
source
sourceDetails
qualifiedName
name
description
displayName
userDescription
classifications {
...classificationFields
}
relatedEntities {
...relatedEntitiesFields
}
assignedTerms {
...assignedTermsFields
}
}
}
Obtenir une entité avec des classifications
- avec toutes les classifications
query {
entities(where: { guid: "<guid>" }) {
guid
typeName
attributes
classifications {
typeName
attributes
}
}
}
- avec des classifications filtrées
query {
entities(where: { guid: "<guid>" }) {
guid
typeName
attributes
classifications(where: { type: { typeName: "<classificationType>" } }) {
typeName
attributes
}
}
}
Obtenir une entité avec des entités associées
- avec toutes les entités associées
query {
entities(where: { guid: "<guid>" }) {
guid
typeName
attributes
relatedEntities {
relationshipAttributeName
relationship {
guid
typeName
attributes
}
entity {
guid
typeName
qualifiedName
attributes
}
}
}
}
- avec des entités associées filtrées
query {
entities(where: { guid: "<guid>" }) {
guid
typeName
attributes
relatedEntities(where: { relationshipAttributeName: "<relAttrName1>" }) {
entity {
guid
typeName
qualifiedName
attributes
}
}
}
}
- avec des entités associées filtrées, séparées par des alias
query {
entities(where: { guid: "<guid>" }) {
guid
typeName
attributes
alias1: relatedEntities(where: { relationshipAttributeName: "<relAttrName1>" }) {
entity {
guid
typeName
attributes
}
}
alias2: relatedEntities(where: { relationshipAttributeName: "<relAttrName2>" }) {
entity {
guid
typeName
attributes
}
}
}
}
Obtenir une entité avec des termes de glossaire
- avec tous les termes du glossaire
query {
entities(where: { guid: "<guid>" }) {
guid
typeName
attributes
assignedTerms {
confidence
createdBy
description
expression
steward
source
status
term {
qualifiedName
name
shortDescription
longDescription
}
}
}
}
- avec des termes de glossaire filtrés
query {
entities(where: { guid: "<guid>" }) {
guid
typeName
attributes
assignedTerms {
confidence
createdBy
description
expression
steward
source
status
term {
qualifiedName
name
shortDescription
longDescription
}
}
}
}
Filtrage (préversion)
Les performances de la correspondance exacte pour « GUID » et « Qualified-Name » sont garanties dans les exemples fournis dans la section « requêtes de base ». Toutefois, il existe certaines limitations pour d’autres modèles de filtrage :
- Filtrage sur les champs non indexés : les champs autres que GUID & nom qualifié ne sont actuellement pas indexés (comme exemple dans la section « Filtre simple »). Le filtrage sur des champs non indexés sans critères sur guid/nom qualifié entraîne une analyse de table et peut entraîner des problèmes de performances sur les jeux de données volumineux.
- Filtrage imbriqué : comme pour les champs non indexés, le filtrage imbriqué peut entraîner des analyses de table, ce qui peut entraîner des problèmes de performances sur des jeux de données volumineux. Par exemple, la recherche d’une entité avec une classification/un terme/une entité liée.
Malgré ces limitations, ce modèle d’appel est supérieur au filtrage côté client et est actuellement utilisé par notre client interne.
Filtre simple
Interroger des entités par type et attributs système
query {
entities(
where: {
type: { typeName: "<entityType>" }
name: { eq: "<value>" }
createTime: { timerange: LAST_7D }
updateTime: { gt: "<timestamp>" }
}
) {
guid
typeName
qualifiedName
attributes
}
}
Interroger des entités par type et attributs
query {
entities(
where: {
type: { typeName: "<entityType>" }
attribute: { field: "<attrName>",operator: eq, value: "<attrValue>" }
}
) {
guid
typeName
qualifiedName
attributes
}
}
Interroger des entités par type et attributs métier
query {
entities(
where: {
type: { typeName: "<entityType>" }
businessAttribute: { field: "<BusinessMetadataName>.<BusinessAttributeName>", operator: eq, value: "<BizAttrValue>" }
}
) {
guid
typeName
qualifiedName
attributes
}
}
Interroger des entités par collection
Actuellement, ce modèle de requête n’est pas pris en charge pour les sous-ensembles.
query {
entities(
where: {
type: { typeName: "<entityType>" }
collectionID: "<collectionId>"
}
) {
guid
typeName
qualifiedName
attributes
}
}
Combinaison de filtres
Les clés d’un object(map) sont combinées en tant qu’AND logique.
query {
entities(
where: {
type: { typeName: "<entityType>" }
or: [
{
and: [
{ attribute: { field: "<attrName1>", value: "<attrValue1>" } }
{ attribute: { field: "<attrName2>", value: "<attrValue2>" } }
]
}
{
not: {
businessAttribute: {
field: "<BusinessMetadataName>.<BusinessAttributeName>", value: "<BizAttrValue>"
}
}
}
]
}
) {
guid
typeName
qualifiedName
attributes
}
}
Filtre imbriqué
Actuellement, ce modèle de requête n’est pas pris en charge pour les sous-ensembles.
Interroger l’entité par classification
query {
entities(
where: {
classification: { type: { typeName: "<classificationType>", includeSubTypes: true } }
}
) {
guid
typeName
qualifiedName
attributes
}
}
Interroger une entité par entité associée
query {
entities(
where: {
relatedEntity: {
relationshipAttributeName: "<relAttrName>"
entity: {
type: { typeName: "<entityType>" }
}
}
}
) {
guid
typeName
qualifiedName
attributes
}
}
Interroger l’entité par termes de glossaire
query {
entities(
where: {
assignedTerm: {
term: {
qualifiedName: { eq: "<termName>" }
}
}
}
) {
guid
typeName
qualifiedName
attributes
}
}
Autres requêtes
Obtenir la relation
query {
relationships(where: { guid: "<guid>" }) {
guid
typeName
attributes
end1 {
guid
typeName
qualifiedName
attributes
}
end2 {
guid
typeName
qualifiedName
attributes
}
}
}
Exemple de réponse :
{
"data": {
"relationships": [
{
"guid": "...",
"typeName": "ExampleRelationship",
"attributes": {},
"end1": {
"guid": "...",
"typeName": "column",
"qualifiedName": "...",
"attributes": {}
},
"end2": {
"guid": "...",
"typeName": "column",
"qualifiedName": "...",
"attributes": {}
}
}
]
}
}
Traçabilité
Obtenir un jeu de données avec des jeux de données en aval
Cette requête retourne les jeux de données en aval à 2 degrés.
query {
entities(where: { guid: "<guid>" }) {#dataset
guid
typeName
qualifiedName
relatedEntities(where: { relationshipAttributeName: "inputToProcesses" }) {
entity {#process
guid
typeName
relatedEntities(where: { relationshipAttributeName: "outputs" }) {
entity {#dataset
guid
typeName
qualifiedName
relatedEntities(where: { relationshipAttributeName: "inputToProcesses" }) {
entity {#process
guid
typeName
qualifiedName
relatedEntities(where: { relationshipAttributeName: "outputs" }) {
entity {#dataset
guid
typeName
qualifiedName
}
}
}
}
}
}
}
}
}
}
Exemple de réponse :
{
"data": {
"entities": [
{
"guid": "...",
"typeName": "Dataset",
"qualifiedName": "...",
"relatedEntities": [
{
"entity": {
"guid": "...",
"typeName": "Process",
"relatedEntities": [
{
"entity": {
"guid": "...",
"typeName": "Dataset",
"qualifiedName": "...",
"relatedEntities": [
{
"entity": {
"guid": "...",
"typeName": "Process",
"relatedEntities": [
{
"entity": {
"guid": "...",
"typeName": "Dataset",
"qualifiedName": "..."
}
}
]
}
}
]
}
}
]
}
}
]
}
]
}
}
Limitations
Limitation de la profondeur de récupération des requêtes :
Les requêtes sont limitées par la profondeur des requêtes. La profondeur maximale est de 5. Par exemple, la requête suivante échoue :
query {
entities { #depth 1
relatedEntities { #depth 2
entity {
relatedEntities { #depth 3
entity {
assignedTerms{ #depth 4
term {
classifications { #depth 5
...
}
}
}
relatedEntities { #depth 4
entity {
assignedTerms{ #depth 5
term {
classifications { #depth 6
...
}
}
}
}
}
}
}
}
}
}
}
Limitation du coût de récupération au moment de l’exécution :
Les requêtes sont limitées par le coût d’exécution des requêtes. Le coût maximal autorisé est défini à 100 unités.
Le coût d’extraction d’exécution est calculé chaque fois que nous visons à récupérer des entités associées, des termes attribués ou des classifications pour une entité ou un terme donné.
Exemple
Prenons l’exemple d’un scénario où nous interrogeons 3 entités, chacune avec deux entités associées. Le calcul du coût est le suivant :
- Une unité pour la requête racine
- Trois unités pour chaque entité de niveau 1
Par conséquent, le coût total de cette requête serait 1 (root query) + 3 (level-1 entities) = 4.
Performances de filtrage
Le filtrage est actuellement en préversion et présente certaines limitations. Pour plus d’informations , consultez Filtrage.
GraphQL requêtes commencent par une requête racine qui récupère les nœuds de niveau supérieur. Il récupère ensuite de manière récursive les nœuds associés.
Les performances d’une requête imbriquée sont principalement déterminées par la requête racine, car les nœuds associés sont extraits à partir d’un point de départ connu, similaire à une clé étrangère dans SQL.
Pour optimiser les performances, il est essentiel d’éviter les requêtes racines génériques qui pourraient déclencher une analyse de table sur les nœuds de niveau supérieur.
Par instance, la requête suivante peut entraîner des problèmes de performances sur des jeux de données volumineux, car le name champ n’est pas indexé :
query {
entities(where: { name: { eq: "<value>" } }) {
guid
typeName
attributes
relatedEntities {
entity {
guid
typeName
attributes
}
}
}
}
Pour éviter de tels problèmes de performances, veillez à appliquer un filtre sur guid ou qualifiedName.
Étapes suivantes
Gérer les APIREST du plan de données Microsoft Purview des sources de données