Beginning Lessons with Fabric API Programming
10% of your time writing code, 90% of your time Doh!

Beginning Lessons with Fabric API Programming

Subtitle: or how I learned to stop worrying and love the Bearer token... eventually

Welcome to my crash course on getting started with Fabric API programming — or as I like to call it, “the slow descent into GUID-based madness.” If you’re expecting a tranquil API onboarding experience where everything just works... well, you must be new here.

I had a happy weekend coding with the cat in the garden. He was playful until he saw my code and now he's terrified but at least the sun was out and I was by the river, so tranquil.

Let’s dive into the key lessons I learned while trying to build something useful — and retaining just enough sanity to blog about it.

Lesson 1: Watch Your Headers

I spent two hours wondering why my API calls were failing. I checked the workspace. I checked the Lakehouse access. I sacrificed a test tenant to the Microsoft gods. Nothing worked.

The problem?

Authorization: <actual-token-here>        

Yeah. I forgot the word Bearer. That’s it. No Bearer, no joy. Two hours of my life that I’ll never get back. It took less time to write the code. But sure, fail slow in the garden — at least it's scenic.

Lesson 2: App Registrations – Do It Right the First Time

Do yourself a favour: don’t rely on your user identity. Register an app, give it permission, and delegate access to the Fabric APIs like a grown-up. You’ll thank yourself when you're not debugging token scopes at 2am.

And yes, I used MSAL. No, I don’t want to talk about how many times I messed up the redirect URI.

If you need a reusable token generator, here’s your new best friend:

private static async Task<string> AcquireBearerTokenAsync(FabricConfiguration? configuration)
{
    Uri authority = new Uri($"https://login.microsoftonline.com/{configuration!.TenantId}/v2.0");
    string[] scopes = ["https://api.fabric.microsoft.com/.default"];

    if (configuration.BrowserAuth)
    {
        IPublicClientApplication publicClient = PublicClientApplicationBuilder
            .Create(configuration.ApplicationId)
            .WithAuthority(authority)
            .WithRedirectUri("http://localhost")
            .Build();

        var result = await publicClient
            .AcquireTokenInteractive(scopes)
            .WithPrompt(Prompt.SelectAccount)
            .ExecuteAsync();
        return result.AccessToken;
    }
    else
    {
        IConfidentialClientApplication confClient = ConfidentialClientApplicationBuilder
            .Create(configuration.ApplicationId)
            .WithClientSecret(configuration.ApplicationKey)
            .WithAuthority(authority)
            .Build();

        var result = await confClient

            .AcquireTokenForClient(scopes)
            .ExecuteAsync();
        return result.AccessToken;
    }
}        

Yes, it's long.

Lesson 3: Refit, simple

Darren intro'd me to this. Do yourself another favour: use libraries like Refit to interface with Fabric APIs. I knocked up this gem in no time:

[Get("/v1/workspaces/{workspaceId}/lakehouses/{lakehouseId}/tables")]
Task<FabricTableResponse> GetTablesAsync(
    [AliasAs("workspaceId")] string workspaceId,
    [AliasAs("lakehouseId")] string lakehouseId,
    [AliasAs("maxResults")] [Query] int maxResults,
    [AliasAs("continuationToken")] [Query] string? continuationToken = null);        

Magic. Now go forth and abstract.

Lesson 4: Fabric’s Friendly Names Are... Not Friendly

Let’s talk about IDs. Fabric APIs don’t use names. They use GUIDs. And sometimes they expect the Lakehouse ID. Sometimes the Workspace ID. Sometimes both. But never the friendly name. Because... reasons.

You’re going to need to keep a lookup table or start whispering GUIDs in your sleep.

Lesson 5: Don’t Expect SQL Server Tools to Play Nice

Tried using SSMO to get table medadata? Yeah, don’t. You’ll get a "transport error" faster than a Microsoft blog post says "just click here".

Behind the scenes, it’s doing some magical routing from xxx.datawarehouse.fabric.microsoft.com to nowhere. The SQL endpoint exists. Your hope does not.

Lesson 6: Even SqlClient Can’t Save You Sometimes

You can use Microsoft.Data.SqlClient to connect to the Lakehouse SQL Endpoint. You will get a connection. You might get a result. You probably won’t get a SqlDataReader.

And if you use TrustServerCertificate=true — say goodbye to clarity and hello to weird errors so drop it from your connection string. Ask me how I know.

Bonus Tip: Use the sys DB to get SQL metadata

There is light in this tunnel. You can discover Lakehouse tables via SQL. You can also hit the API:

[Get("/v1/workspaces/{workspaceId}/lakehouses/{lakehouseId}")]
Task<FabricLakehouse> GetLakehousePropertiesAsync(
    [AliasAs("workspaceId")] string workspaceId,
    [AliasAs("lakehouseId")] string lakehouseId);        

Use that to get your SQL endpoint properties. You’ll be spoon-fed the server string, ready for whatever connectivity drama awaits.

Final Thoughts

  • Fabric APIs are good, but rough around the edges.
  • You’ll spend time working around the platform, not in it.
  • Once configured, the experience is… okay. Like tea that’s been microwaved, it technically works.

I'll be doing a lot of Fabric work so will post little and often. Until then: compile often, log everything, and remember to add "Bearer " to your auth header before you write a blog post about how broken the API is.

Happy trails!


Vogon? As in Hitchhiker’s Guide to the Galaxy?

Like
Reply

To view or add a comment, sign in

More articles by Richard Conway

Others also viewed

Explore content categories