Code Monkey home page Code Monkey logo

restlibraries's Introduction

RestLibraries

A project aimed to compare different .NET API client libraries.

Use case :

  • A user trying to save a payment in a different currency
  • An external call to an API giving back rates between two currency
    • For benchmark test purpose, it has been hardcoded with the payload of Free forex API

Project

Simple API endpoint taking payment data and using different library to call a external API.

  • No persistence as it's aimed to measure library performance

RestLibraries.API

Minimal API aimed to avoid rate limiting and network latency for Benchmark performances

docker build -t restlibraries-api . docker run -d -p 80:80 --name restlibraries-api restlibraries-api

RestLibraries

Project respecting Clean Architecture & using one endpoint / handler doing the same process for each library.

  • Take a payment payload

  • If currency is different, makes an external API call to get the rates between currency

  • Return payment result

  • An post payment endpoint per API client library :

Benchmark

Running the bench mark

  • cd .\RestLibraries\test\BenchMarkTests
  • dotnet test --filter "Category=HttpClient" -c Release
  • dotnet test --filter "Category=Refit" -c Release
  • dotnet test --filter "Category=Restsharp" -c Release

Issue & note

Benchmark aren't running smoothly due to .NetCore HttpClient connection pool management (build with HttpClientFactory under the hood). It's still a bit blurry and I may have made a rookie mistake somewhere. Dotnet runtime github issue

   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource<System.Int32>.GetResult(Int16 token)
   at System.Net.Http.HttpConnection.InitialFillAsync(Boolean async)
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)

I've tried a few things without luck :

  • Make sure HttpClient was implemented as a singleton to make sure that it's not disposed
  • Playing with MaxConnectionsPerServer settings for HttpClient
    .ConfigurePrimaryHttpMessageHandler(() =>
    {
        return new SocketsHttpHandler()
        {
            MaxConnectionsPerServer = 10
        };
    })

Result

  1. HttpClient
BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2728/22H2/2022Update)
11th Gen Intel Core i7-11800H 2.30GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK=6.0.405
  [Host]   : .NET 6.0.13 (6.0.1322.58009), X64 RyuJIT AVX2
  ShortRun : .NET 6.0.13 (6.0.1322.58009), X64 RyuJIT AVX2

Job=ShortRun  IterationCount=3  LaunchCount=1  
WarmupCount=3  
Method Mean Error StdDev Gen0 Gen1 Allocated
BenchMark_HttpClient 8.763 μs 4.231 μs 0.2319 μs 0.2289 0.1221 3.18 KB

Updated (With System.Net.Http.Json deserialisation)

Method Mean Error StdDev Gen0 Gen1 Allocated
BenchMark_HttpClient 7.752 μs 42.137 μs 2.310 μs 0.3510 0.1907 4.28 KB
  1. Refit
BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2728/22H2/2022Update)
11th Gen Intel Core i7-11800H 2.30GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK=6.0.405
  [Host]   : .NET 6.0.13 (6.0.1322.58009), X64 RyuJIT AVX2
  ShortRun : .NET 6.0.13 (6.0.1322.58009), X64 RyuJIT AVX2

Job=ShortRun  IterationCount=3  LaunchCount=1  
WarmupCount=3  
Method Mean Error StdDev Gen0 Gen1 Allocated
BenchMark_Refit 25.26 μs 28.64 μs 1.570 μs 0.7324 0.0610 9.11 KB
  1. Restsharp

Only library to throw socket exception with Job.ShortRun

BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2728/22H2/2022Update)
11th Gen Intel Core i7-11800H 2.30GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK=6.0.405
  [Host]   : .NET 6.0.13 (6.0.1322.58009), X64 RyuJIT AVX2
  ShortRun : .NET 6.0.13 (6.0.1322.58009), X64 RyuJIT AVX2

Job=ShortRun  IterationCount=3  LaunchCount=1  
WarmupCount=3  
Method Mean Error StdDev Gen0 Gen1 Allocated
BenchMark_Restsharp 82.16 μs 238.85 μs 13.09 μs 2.4414 0.7324 26.81 KB

With singleton

|              Method |     Mean |    Error |   StdDev |   Gen0 |   Gen1 | Allocated |
|-------------------- |---------:|---------:|---------:|-------:|-------:|----------:|
| BenchMark_Restsharp | 116.4 μs | 352.7 μs | 19.33 μs | 2.4414 | 0.9766 |  29.62 KB |

Wrap-up

As all software engineering question, best answer would be it depends.

  1. HttpClient
    • It will induce a bit more boiler plate due to HttpRequest exception handling
    • Best performance usage for API endpoint needing an high throughput
      • I'd consider this if DB access isn't a bottleneck & endpoint are called a lot
    • Easy to make mistakes with disposable objects (stream, ...)
  2. Refit
    • Library with the least amount of boilerplate
    • Performance isn't that far for HttpClient (need to confirm with huge json payload)
    • Library hasn't been updated since 08/02/2022
  3. Restsharp
    • Less boilerplate than HttpClient but more than Refit
    • Benchmark looks to have too much error to be reliable except memory allocation
    • Active development

Further reading :

restlibraries's People

Contributors

hmath343 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.