Calling all APIs… How to use Flurl with C#

I, like many software developers these days, spend a lot of time talking to APIs. Not literally (of course!) but I do believe that choosing the right API client library can really help to boost your productivity and as a bonus, you can end up with much cleaner code.

My ‘go-to’ solution at the moment for communicating with HTTP APIs when I’m using .NET is a package called ‘Flurl’.

So what is Flurl?

Let’s have a look at what the Flurl website has to say.

Flurl is a modern, fluent, asynchronous, testable, portable, buzzword-laden URL builder and HTTP client library for .NET.

Flurl, as in ‘Fluent URL’, makes it super-easy to interact with APIs and cuts out much of the additional plumbing code which would otherwise be needed to handle things like authentication and serialization. It works with the .NET Framework and .NET Core, as well as Xamarin projects etc. so it’s got you covered.

How to use it

First of all, you’ll want to install the Flurl HTTP NuGet package into your project.

Here’s a simple example of how to call an API endpoint with Flurl and get a result back.

// Get a list of todos from the 'JSONPlaceholder' API.
var todos = await "https://jsonplaceholder.typicode.com"
                  .AppendPathSegment("todos")
                  .SetQueryParams(new { userId = 1 })
                  .GetJsonAsync<IEnumerable<Todo>>();

As you can see, the ‘fluent’ syntax is highly readable and the code is very concise. It’s really nice that the serialization from JSON to your .NET object is handled automatically.

In the sample code, you’ll notice that the Flurl method calls such as AppendPathSegment are simply extension methods on the .NET string type. Although RestSharp is another nice example of a .NET API client library, with Flurl there’s no need to create any superfluous classes for API clients or requests to get the job done. You can even omit the type from the GetJsonAsync method call and get a dynamic object back if you don’t need a strongly-typed model.

When it comes to posting to an API it’s just as straightforward as making GET requests. The example code below demonstrates how to make a POST request and receive the content which is returned from the API call.

var todo = new Todo { Title = "Buy milk", UserId = 1 };
 
var result = await "https://jsonplaceholder.typicode.com"
                   .AppendPathSegment("todos")
                   .PostJsonAsync(todo)
                   .ReceiveJson<Todo>();

There are lots of other extension methods you can avail of such as PatchJsonAsync, PutJsonAsync and PostStringAsync.

Note that in the code samples I’m using the JSONPlaceholder API. This is a very useful website for testing out API client libraries and for occasions where you need to mock something up quickly. There’s no authentication needed for the dummy data that it returns so it’s very easy to start calling endpoints and carry out your experiments.

When you use Flurl to connect to an API that requires authentication, let’s say OAuth authentication, just add a call to WithOAuthBearerToken and pass in your token string. Simple.

Testing

It would be remiss of me not to mention the rather nice unit testing features that Flurl has to offer.

Here’s an example of how to test an API endpoint, assuming that the CreateTodoAsync method returns the result of an API call using the Flurl PostJsonAsync method.

using (var httpTest = new HttpTest())
{
    // Arrange.
    httpTest.RespondWith("OK", 200);
 
    // Act.
    await CreateTodoAsync();
 
    // Assert.
    httpTest.ShouldHaveCalled("https://jsonplaceholder.typicode.com/todos*")
            .WithVerb(HttpMethod.Post)
            .WithContentType("application/json");
}

Again, Flurl greatly simplifies things for us and makes it easy to mock responses and check our expectations.

All in all, Flurl provides an extensive set of tools that do a great job of making code more readable, simpler to test and easy to maintain.

Where can I learn more?

The Flurl docs do a very good job of documenting the key things that are possible with the library and they discuss how to configure settings, how to handle errors and more.

The Flurl GitHub repository is also a great place to find out more about Flurl and you can dig into the source code and see how it all works if you are interested.

I’ve also created a GitHub repository that demonstrates a working sample of the most basic usage of Flurl in a .NET Core console app.

Alternatives to Flurl

I’ve already mentioned RestSharp, however, I really do recommend using Flurl for anything new that you are developing, whether you are using standard .NET or .NET Core.

Alternatively, if you like to keep things fluent you might want to check out FluentRest. It is a lightweight wrapper over the built-in .NET HttpClient and provides similar features to that of Flurl without hiding the HttpClient dependency behind a string.


I hope you enjoyed this post! Comments are always welcome and I respond to all questions.

If you like my content and it helped you out, please check out the button below 🙂

Comments

John

Great blog! Very useful and informative!

November 18, 2019

Jonathan Crozier

Thanks, John 🙂

November 18, 2019

Paul

Hey… Looking for Flurl examples and landed here.

Do you have more examples on how to use Flurl in async mode for long running GET/POST calls? The Flurl documentation make a big stink about how it’s an Async library but offers few, if any real-world working examples of how to implement it.

July 13, 2020

Jonathan Crozier

Hi Paul,

The majority of the examples within the Flurl documentation are making GET/POST calls asynchronously using the await keyword.

When you say ‘long running’, how long are these calls likely to take or what is your specific scenario?

July 14, 2020

Abhijit

I tried to use FLURL in a new project I started. I am a bit stuck since every call I am making to the webAPI is returning a 404 error. A search for FLURL got me to your blog. One of the things I like about FLURL is the chaining mechanism.

April 12, 2021

Jonathan Crozier

Hi Abhijit,

When calling an API if you get a HTTP 404 (Not Found) error, this usually means that either the URL path is incorrect, or there are no items available to return for the specified API endpoint.

You could try calling the API using another tool such as Postman or curl to see if you’re getting a 404 error there too. I have another blog post on how to use curl here: https://jonathancrozier.com/blog/diving-into-curl-as-an-api-developer

April 12, 2021