{"id":3495,"date":"2024-02-21T14:58:43","date_gmt":"2024-02-21T19:58:43","guid":{"rendered":"https:\/\/www.kuriosit.ca\/?p=3495"},"modified":"2025-03-10T14:15:44","modified_gmt":"2025-03-10T18:15:44","slug":"power-query-odata-web-and-vsts","status":"publish","type":"post","link":"https:\/\/www.kuriosit.ca\/en\/power-query-odata-web-et-vsts\/","title":{"rendered":"Power Query - OData, Web and VSTS"},"content":{"rendered":"<style>.wp-block-kadence-column.kb-section-dir-horizontal > .kt-inside-inner-col > .kt-info-box3495_9f142f-d2 .kt-blocks-info-box-link-wrap{max-width:unset;}.kt-info-box3495_9f142f-d2 .kt-blocks-info-box-link-wrap{border-top:0px solid var(--global-palette7, #eeeeee);border-right:0px solid var(--global-palette7, #eeeeee);border-bottom:0px solid var(--global-palette7, #eeeeee);border-left:0px solid var(--global-palette7, #eeeeee);border-top-left-radius:0px;background:#ffffff;padding-top:0px;padding-right:0px;padding-bottom:25px;padding-left:0px;}.kt-info-box3495_9f142f-d2.wp-block-kadence-infobox{max-width:100%;}.kt-info-box3495_9f142f-d2 .kadence-info-box-image-inner-intrisic-container{max-width:100px;}.kt-info-box3495_9f142f-d2 .kadence-info-box-image-inner-intrisic-container .kadence-info-box-image-intrisic{padding-bottom:100%;width:297px;height:0px;max-width:100%;}.kt-info-box3495_9f142f-d2 .kadence-info-box-icon-container .kt-info-svg-icon, .kt-info-box3495_9f142f-d2 .kt-info-svg-icon-flip, .kt-info-box3495_9f142f-d2 .kt-blocks-info-box-number{font-size:50px;}.kt-info-box3495_9f142f-d2 .kt-blocks-info-box-media{border-radius:200px;overflow:hidden;border-top-width:0px;border-right-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:20px;padding-right:20px;padding-bottom:20px;padding-left:20px;margin-top:0px;margin-right:10px;margin-bottom:0px;margin-left:0px;}.kt-info-box3495_9f142f-d2 .kt-blocks-info-box-media .kadence-info-box-image-intrisic img{border-radius:200px;}.kt-info-box3495_9f142f-d2 .kt-infobox-textcontent h2.kt-blocks-info-box-title{padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;margin-top:5px;margin-right:0px;margin-bottom:10px;margin-left:0px;}.kt-info-box3495_9f142f-d2 .kt-infobox-textcontent .kt-blocks-info-box-text{color:var(--global-palette3, #1A202C);}.wp-block-kadence-infobox.kt-info-box3495_9f142f-d2 .kt-blocks-info-box-text{font-size:18px;font-weight:400;}.kt-info-box3495_9f142f-d2 .kt-blocks-info-box-link-wrap:hover .kt-blocks-info-box-text{color:var(--global-palette1, #3182CE);}.kt-info-box3495_9f142f-d2 .kt-blocks-info-box-learnmore{background:transparent;border-width:0px 0px 0px 0px;padding-top:4px;padding-right:8px;padding-bottom:4px;padding-left:8px;margin-top:10px;margin-right:0px;margin-bottom:10px;margin-left:0px;}@media all and (max-width: 1024px){.kt-info-box3495_9f142f-d2 .kt-blocks-info-box-link-wrap{border-top:0px solid var(--global-palette7, #eeeeee);border-right:0px solid var(--global-palette7, #eeeeee);border-bottom:0px solid var(--global-palette7, #eeeeee);border-left:0px solid var(--global-palette7, #eeeeee);}}@media all and (max-width: 767px){.kt-info-box3495_9f142f-d2 .kt-blocks-info-box-link-wrap{border-top:0px solid var(--global-palette7, #eeeeee);border-right:0px solid var(--global-palette7, #eeeeee);border-bottom:0px solid var(--global-palette7, #eeeeee);border-left:0px solid var(--global-palette7, #eeeeee);}}<\/style>\n<div class=\"wp-block-kadence-infobox kt-info-box3495_9f142f-d2\"><a class=\"kt-blocks-info-box-link-wrap info-box-link kt-blocks-info-box-media-align-left kt-info-halign-left\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"https:\/\/www.linkedin.com\/in\/simon-pierre-morin-43849bb2\/\"><div class=\"kt-blocks-info-box-media-container\"><div class=\"kt-blocks-info-box-media kt-info-media-animate-none\"><div class=\"kadence-info-box-image-inner-intrisic-container\"><div class=\"kadence-info-box-image-intrisic kt-info-animate-none\"><div class=\"kadence-info-box-image-inner-intrisic\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.kuriosit.ca\/wp-content\/uploads\/2024\/04\/Simon-Pierre-Morin.jpg\" alt=\"\" width=\"297\" height=\"297\" class=\"kt-info-box-image wp-image-4589\" title=\"\"><\/div><\/div><\/div><\/div><\/div><div class=\"kt-infobox-textcontent\"><p class=\"kt-blocks-info-box-text\">By Simon-Pierre Morin, Eng. <\/p><\/div><\/a><\/div>\n\n\n<style>.kb-table-of-content-nav.kb-table-of-content-id3495_908ad1-3c .kb-table-of-content-wrap{padding-top:var(--global-kb-spacing-xxs, 0.5rem);padding-right:var(--global-kb-spacing-xxs, 0.5rem);padding-bottom:var(--global-kb-spacing-xxs, 0.5rem);padding-left:var(--global-kb-spacing-sm, 1.5rem);border-top:1px solid var(--global-palette2, #2B6CB0);border-right:1px solid var(--global-palette2, #2B6CB0);border-bottom:1px solid var(--global-palette2, #2B6CB0);border-left:1px solid var(--global-palette2, #2B6CB0);border-top-left-radius:16px;}.kb-table-of-content-nav.kb-table-of-content-id3495_908ad1-3c .kb-table-of-contents-title-wrap{padding-top:0px;padding-right:0px;padding-bottom:0px;padding-left:0px;}.kb-table-of-content-nav.kb-table-of-content-id3495_908ad1-3c .kb-table-of-contents-title{font-size:var(--global-kb-font-size-md, 1.25rem);font-weight:regular;font-style:normal;text-transform:uppercase;}.kb-table-of-content-nav.kb-table-of-content-id3495_908ad1-3c .kb-table-of-content-wrap .kb-table-of-content-list{font-size:var(--global-kb-font-size-md, 1.25rem);font-weight:regular;font-style:normal;margin-top:var(--global-kb-spacing-sm, 1.5rem);margin-right:0px;margin-bottom:0px;margin-left:0px;}.kb-table-of-content-nav.kb-table-of-content-id3495_908ad1-3c .kb-table-of-content-wrap .kb-table-of-content-list .kb-table-of-contents__entry:hover{color:var(--global-palette1, #3182CE);}@media all and (max-width: 1024px){.kb-table-of-content-nav.kb-table-of-content-id3495_908ad1-3c .kb-table-of-content-wrap{border-top:1px solid var(--global-palette2, #2B6CB0);border-right:1px solid var(--global-palette2, #2B6CB0);border-bottom:1px solid var(--global-palette2, #2B6CB0);border-left:1px solid var(--global-palette2, #2B6CB0);}}@media all and (max-width: 767px){.kb-table-of-content-nav.kb-table-of-content-id3495_908ad1-3c .kb-table-of-content-wrap{border-top:1px solid var(--global-palette2, #2B6CB0);border-right:1px solid var(--global-palette2, #2B6CB0);border-bottom:1px solid var(--global-palette2, #2B6CB0);border-left:1px solid var(--global-palette2, #2B6CB0);}}<\/style>\n\n\n<p class=\"wp-block-paragraph\">As part of the<a href=\"https:\/\/app.swapcard.com\/widget\/event\/agile-tour-quebec-2023\/planning\/UGxhbm5pbmdfMTYwNjQyNA==\" target=\"_blank\" rel=\"noreferrer noopener\">Agile tour Qu\u00e9bec 2023<\/a> and the Eastern Townships PowerBI community, I've briefly presented solutions for connecting to web sources. In this post, I'll go into the technical details of these connectors, pointing out their advantages and the points to watch out for.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"text-transform:none\">OData.Feed<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is a connector for reading OData streams. These data streams (called <em>feed<\/em>) are still fairly widespread when large quantities of data are involved, notably for logged data or for instruments that historicize their measurements in real time. There are also several services using analytical cubes or similar technologies that return their data using a <em>feed<\/em> rather than an HTTP-GET response in JSON.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One of the main advantages of <em>feeds<\/em> is that the response received uses natural pagination. As the response only returns the first few results to save resources, as soon as we try to display the rest, we get it thanks to the mechanism that gives us the next page. Be warned, however, that if your system requests all the data at once, you'll lose this benefit. Internally, PowerQuery and PowerBI will cache the results already obtained and only query the feed to obtain the information on the next page.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The syntax is very simple<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>OData.Feed(queryURL, header, options)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Although optional, many services require you to specify the :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>OData.Feed(queryURL, null, [Implementation=\"2.0\"])<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The URL structure of a <em>feed<\/em> is as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>protocol<\/li>\n\n\n\n<li>domain<\/li>\n\n\n\n<li>OData path and version<\/li>\n\n\n\n<li>feed<\/li>\n\n\n\n<li>request<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">So for the following query<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:\/\/monserveur.ca\/_odata\/v4.0-preview\/Employee?$select=id,firstname,lastname,email<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-table is-style-regular\"><table><thead><tr><th><strong>Structure<\/strong><\/th><th><strong>URL element<\/strong><\/th><\/tr><\/thead><tbody><tr><td>Protocol<\/td><td>HTTPS<\/td><\/tr><tr><td>Domain<\/td><td>monserveur.ca<\/td><\/tr><tr><td>OData path<\/td><td>\/_odata\/v4.0-preview\/<\/td><\/tr><tr><td>Flux (feed)<\/td><td>Employee<\/td><\/tr><tr><td>Request<\/td><td>$select=id,firstname,lastname,email<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">association of query structure with URL structure<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">In this example, the OData path has been simplified. Some servers have an access path between the domain and the portion marked <mark style=\"background-color:#EDF2F7\" class=\"has-inline-color\">_odata<\/mark> of the URL. Please note that OData is available in <a href=\"https:\/\/www.odata.org\/documentation\/\" target=\"_blank\" rel=\"noopener\">several versions<\/a> and that each service can implement one or more versions. Generally speaking, the version used is specified in the URL (although there may be exceptions).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that the query syntax does not allow it to be set in the <em>Query<\/em>. Please also note that connections are made via <em>feed<\/em> &nbsp;and not per request. So if you have more than one request to the same data stream, authentication information will only be requested once. On the other hand, if you have different <em>feeds<\/em>you'll need to authenticate for each of them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For more information, visit <a href=\"https:\/\/learn.microsoft.com\/fr-ca\/powerquery-m\/odata-feed\" target=\"_blank\" rel=\"noopener\">official documentation<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Benefits<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Fast data acquisition<\/li>\n\n\n\n<li>Smooth, automatic pagination<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Disadvantage<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Tends to multiply connections<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"text-transform:none\">Web.Contents<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is the generic connector for REST APIs. Versatile, it can be used to invoke any GET or POST request. What's more, thanks to the \"RelativePath\" property, it allows only one connection per base URL (the non-changing part of our requests).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Make sure that your base URL requires only one connection authority (including anonymous connections). For example, if you want to connect to a Jira Cloud server and the address had this template <mark style=\"background-color:#EDF2F7\" class=\"has-inline-color\">https:\/\/monentreprise.com\/jira\/Projet1<\/mark>However, your company's rules may restrict authentication information not to the domain, but rather to certain access paths. In this case, your base URL may not be <mark style=\"background-color:#EDF2F7\" class=\"has-inline-color\">https:\/\/monentreprise.com<\/mark>but should rather be <mark style=\"background-color:#EDF2F7\" class=\"has-inline-color\">https:\/\/monentreprise.com\/jira<\/mark> or even include the project name.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here are a few examples of how Web.Contents can be used to return a list of \"Power Query\" search results with a GET request<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>The direct method<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>Web.Content(\"https:\/\/bing.com\/search?q=Power+Query\")<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Using RelativePath only<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>Web.Contents(\n    \"https:\/\/www.bing.com\",\n    [\n        RelativePath = \"search?q=Power+Query\"\n    ]\n)<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Using RelativePath and Query<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>Web.Contents(\n    \"https:\/\/www.bing.com\",\n    [\n        RelativePath = \"search\",\n        Query = [q = \"Power Query\"]\n    ]\n)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here is an example of a POST request<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>let\n    headers = [# \"Content-Type\" = \"application\/json\"],\n    postData = Json.FromValue(\n        Json.Document(\n           \"{\n               \"queryInfo\": {\n               \"\"problemType\"\": \"\"Polynomial\"\",\n               \"\"stepTypes\"\": [\n                  \"\"quadratic expression with fraction with 1 variables\"\",\n                   \"1 variables\"\"\n               ],\n               \"\"market\"\": \"\"en\"\"\n             }\n           }\"\n      )\n   ),\n    relPath = \"cameraexp\/api\/v1\/generateCustomBingAnswers\",\n    response = Web.Contents(\n        \"https:\/\/mathsolver.microsoft.com\/ \",\n        [\n            Headers = headers,\n            Content = postData,\n            RelativePath = relPath\n        ]\n    ),\n    jsonResponse = Json.Document(response)\nin\n    jsonResponse<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Note that the GET or POST identifier is never mentioned in Web.Contents. The presence of the Content property tells the function that it is a POST. It should also be noted that it is possible to use RelativePath, although it is optional. However, it is recommended to use it if several requests are made to the same server, to avoid multiplying connectors.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For more information, visit <a href=\"https:\/\/learn.microsoft.com\/fr-ca\/powerquery-m\/web-contents\" target=\"_blank\" rel=\"noopener\">official documentation<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It's worth noting that OData streams can also be invoked using the GET method. This technique limits the number of connectors for a single server, but loses the performance capability of OData. It's also important to note that responses will still be paginated and will return a \"nextLink\" response, which must be managed manually using List.Generate.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The technique described below should therefore be used with care, establishing the advantages and disadvantages. In some cases, it's best to continue using OData.Feed for performance, but if your data feeds only return a small set of data and you simply want to avoid managing multiple connectors, here's how to proceed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To do this, we'll continue to use RelativePath, to manage the portion of the <em>feed<\/em> and the URL request.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let's suppose we have the following query:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:\/\/monserveur.ca\/path\/_odata\/v4.0-preview\/Employee?$select=id,firstname,lastname,email<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In this example, let's consider <mark style=\"background-color:#EDF2F7\" class=\"has-inline-color\">https:\/\/monserveur.ca\/path\/_odata\/v4.0-preview\/<\/mark> as our base URL, but we could very well choose to stop after <code>path\/<\/code>. The important thing is not to include the \"data feed\" part and to ensure that the final concatenation gives us the complete URL. Our feed is Employee and the request is <mark style=\"background-color:#EDF2F7\" class=\"has-inline-color\">$select=id,firstname,lastname,email.<\/mark><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Given the structure of an OData query, it's not possible to use Query for the query. So we have to put everything in the RelativePath. However, what will be returned in nextLink is a complete URL. To avoid receiving a dynamic connection message, we'll need to remove the portion of our base URL to return what's left in the next RelativePath.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>URL = \" https:\/\/monserveur.ca\/path\/_odata\/v4.0-preview\/\",<br>feed = \"Employee\",<br>query = \"?$select=id,firstname,lastname,email \",<br>FeedContentFix = List.Generate(<br>&nbsp;&nbsp;&nbsp;&nbsp;() =&gt; Web.Content(url, [RelativePath=feed&amp;query]),<br>&nbsp;&nbsp;&nbsp;&nbsp;each Record.HasFields(_, \"value\"),<br>&nbsp;&nbsp;&nbsp;&nbsp;each (<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Record.HasFields(_, \"@odata.nextLink\")<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;) then (<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nextstep = _[#\"@odata.nextLink\"],<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nextquery = Text.Range(nextstep,Text.PositionOf(nextstep,feed))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; in<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Web.Content(url, [RelativePath=nextquery]),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;) else (<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [context=\"EoF\"]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;),<br>&nbsp;&nbsp;&nbsp;&nbsp;each _[value]<br>),<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Benefits<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use RelativePath<\/li>\n\n\n\n<li>Works with almost all APIs, including OData<\/li>\n\n\n\n<li>Minimizes connectors to the same server\/service<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Disadvantages<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Impossible to use for Azure services<\/li>\n\n\n\n<li>Paginated responses (&gt; 10,000)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"text-transform:none\">VSTS.AccountContents<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is a Microsoft-specific API connector. It uses the same syntax as Web.Contents, with the addition of the \"<em>Version<\/em>\"which is not supported by Web.Contents. (this property is optional, but is present in the wrappers developed by Microsoft to connect to Azure DevOps wiql resources).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It should be noted that the VSTS package (which includes both Feed and AccountContents) detects the organization (sub-domain) without the need for the base URL technique, and will only request authentication data once per organization.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Unfortunately, it is not possible to use VSTS in a data flow hosted on the Power BI service. However, it is usable in other versions of Power Query, whether in Excel or Power BI directly, and can be published without problem.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Another irritant is that the connection will be called VSTS without any further details. So, if you make a report connecting to two separate VSTS sources, both will have the same name with no way of distinguishing the two in the connection manager. The same will apply to your workspace connections. If you have several reports using a VSTS connector, these will be difficult to distinguish in the connection and gateway manager.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Benefits<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Same advantages as Web.Contents<\/li>\n\n\n\n<li>Single sign-on for the entire ADO organization<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Disadvantage<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Limited to Microsoft services<\/li>\n\n\n\n<li>Unique name identical for all connections<\/li>\n\n\n\n<li>Does not work in data flows<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"text-transform:none\">VSTS.Feed<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is a Microsoft-specific connector that is used essentially like OData.Feed and has the same specifications.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Like VSTS.AccountContents, this connector detects the organization and will only create a single connection for the entire organization or sub-domain (including connections using VSTS.AccountContents). However, it has the same disadvantages as the latter.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Benefits<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Same advantages as OData.Feed<\/li>\n\n\n\n<li>Only one connection per organization<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Disadvantage<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Limited to Microsoft services<\/li>\n\n\n\n<li>Unique name identical for all connections<\/li>\n\n\n\n<li>Does not work in data flows<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"text-transform:none\">Still curious?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For those who wish to continue and learn more, I invite them to follow the blog series entitled \"&nbsp;<a href=\"https:\/\/www.kuriosit.ca\/en\/?p=3379\">Series - Creating an agile dashboard with Power BI<\/a>&nbsp;\"by Simon-Pierre Morin and Mathieu Boisvert.<\/p>","protected":false},"excerpt":{"rendered":"<p>Sometimes, our data sources don't come from databases, but rather from web services. Here we present four Power Query connectors to achieve this.<\/p>","protected":false},"author":37,"featured_media":3498,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_kad_blocks_custom_css":"","_kad_blocks_head_custom_js":"","_kad_blocks_body_custom_js":"","_kad_blocks_footer_custom_js":"","_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"categories":[43],"tags":[20,16,15,19,21],"class_list":["post-3495","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-intelligence-daffaires-et-ingenierie-de-donnees","tag-odata-feed","tag-power-bi","tag-power-query","tag-rest-api","tag-vsts"],"acf":[],"taxonomy_info":{"category":[{"value":43,"label":"Intelligence d'affaires et ing\u00e9nierie de donn\u00e9es"}],"post_tag":[{"value":20,"label":"OData Feed"},{"value":16,"label":"Power BI"},{"value":15,"label":"Power Query"},{"value":19,"label":"REST API"},{"value":21,"label":"VSTS"}]},"featured_image_src_large":["https:\/\/www.kuriosit.ca\/wp-content\/uploads\/2024\/02\/feedAI_03.jpeg",1024,1024,false],"author_info":{"display_name":"Simon-Pierre Morin","author_link":"https:\/\/www.kuriosit.ca\/en\/author\/spmorin\/"},"comment_info":0,"category_info":[{"term_id":43,"name":"Intelligence d'affaires et ing\u00e9nierie de donn\u00e9es","slug":"intelligence-daffaires-et-ingenierie-de-donnees","term_group":0,"term_taxonomy_id":43,"taxonomy":"category","description":"","parent":0,"count":5,"filter":"raw","cat_ID":43,"category_count":5,"category_description":"","cat_name":"Intelligence d'affaires et ing\u00e9nierie de donn\u00e9es","category_nicename":"intelligence-daffaires-et-ingenierie-de-donnees","category_parent":0}],"tag_info":[{"term_id":20,"name":"OData Feed","slug":"odata-feed","term_group":0,"term_taxonomy_id":20,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"},{"term_id":16,"name":"Power BI","slug":"power-bi","term_group":0,"term_taxonomy_id":16,"taxonomy":"post_tag","description":"","parent":0,"count":2,"filter":"raw"},{"term_id":15,"name":"Power Query","slug":"power-query","term_group":0,"term_taxonomy_id":15,"taxonomy":"post_tag","description":"","parent":0,"count":2,"filter":"raw"},{"term_id":19,"name":"REST API","slug":"rest-api","term_group":0,"term_taxonomy_id":19,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"},{"term_id":21,"name":"VSTS","slug":"vsts","term_group":0,"term_taxonomy_id":21,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"}],"_links":{"self":[{"href":"https:\/\/www.kuriosit.ca\/en\/wp-json\/wp\/v2\/posts\/3495","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kuriosit.ca\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kuriosit.ca\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kuriosit.ca\/en\/wp-json\/wp\/v2\/users\/37"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kuriosit.ca\/en\/wp-json\/wp\/v2\/comments?post=3495"}],"version-history":[{"count":5,"href":"https:\/\/www.kuriosit.ca\/en\/wp-json\/wp\/v2\/posts\/3495\/revisions"}],"predecessor-version":[{"id":4613,"href":"https:\/\/www.kuriosit.ca\/en\/wp-json\/wp\/v2\/posts\/3495\/revisions\/4613"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.kuriosit.ca\/en\/wp-json\/wp\/v2\/media\/3498"}],"wp:attachment":[{"href":"https:\/\/www.kuriosit.ca\/en\/wp-json\/wp\/v2\/media?parent=3495"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kuriosit.ca\/en\/wp-json\/wp\/v2\/categories?post=3495"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kuriosit.ca\/en\/wp-json\/wp\/v2\/tags?post=3495"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}