{"id":22882391,"url":"https://github.com/loresoft/fluentrest","last_synced_at":"2025-05-16T18:06:56.076Z","repository":{"id":1640487,"uuid":"38906453","full_name":"loresoft/FluentRest","owner":"loresoft","description":"Lightweight fluent wrapper over HttpClient to make REST calls easier","archived":false,"fork":false,"pushed_at":"2025-05-06T07:06:57.000Z","size":629,"stargazers_count":61,"open_issues_count":4,"forks_count":15,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-16T14:19:41.920Z","etag":null,"topics":["fake-handlers","httpclient","httpclientfactory","rest-client"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/loresoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"loresoft"}},"created_at":"2015-07-10T23:28:34.000Z","updated_at":"2025-05-06T07:06:55.000Z","dependencies_parsed_at":"2024-07-29T09:05:58.438Z","dependency_job_id":"74174bf3-dacc-4695-839f-03a5543493ef","html_url":"https://github.com/loresoft/FluentRest","commit_stats":{"total_commits":126,"total_committers":7,"mean_commits":18.0,"dds":0.3492063492063492,"last_synced_commit":"b726e0642d52df0cafbd015f3c32953dac20071e"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loresoft%2FFluentRest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loresoft%2FFluentRest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loresoft%2FFluentRest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loresoft%2FFluentRest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/loresoft","download_url":"https://codeload.github.com/loresoft/FluentRest/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254582905,"owners_count":22095518,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fake-handlers","httpclient","httpclientfactory","rest-client"],"created_at":"2024-12-13T18:17:18.027Z","updated_at":"2025-05-16T18:06:56.056Z","avatar_url":"https://github.com/loresoft.png","language":"C#","readme":"# FluentRest\n\nLightweight fluent wrapper over HttpClient to make REST calls easier\n\n[![Build status](https://github.com/loresoft/FluentRest/actions/workflows/dotnet.yml/badge.svg)](https://github.com/loresoft/FluentRest/actions)\n\n[![NuGet Version](https://img.shields.io/nuget/v/FluentRest.svg?style=flat-square)](https://www.nuget.org/packages/FluentRest/)\n\n[![Coverage Status](https://coveralls.io/repos/github/loresoft/FluentRest/badge.svg?branch=master)](https://coveralls.io/github/loresoft/FluentRest?branch=master)\n\n## Download\n\nThe FluentRest library is available on nuget.org via package name `FluentRest`.\n\nTo install FluentRest, run the following command in the Package Manager Console\n\n    PM\u003e Install-Package FluentRest\n    \nMore information about NuGet package available at\n\u003chttps://nuget.org/packages/FluentRest\u003e\n\n## Development Builds\n\nDevelopment builds are available on the feedz.io feed.  A development build is promoted to the main NuGet feed when it's determined to be stable. \n\nIn your Package Manager settings add the following package source for development builds:\n\u003chttps://f.feedz.io/loresoft/open/nuget/index.json\u003e\n\n## Features\n\n* Fluent request building\n* Fluent form data building\n* Automatic deserialization of response content\n* Plugin different serialization\n* Fake HTTP responses for testing\n* Support HttpClientFactory typed client and middleware handlers\n\n\n## Fluent Request\n\nCreate a form post request\n\n```csharp\nvar client = new HttpClient();\nclient.BaseAddress = new Uri(\"http://httpbin.org/\", UriKind.Absolute);\n\nvar result = await client.PostAsync\u003cEchoResult\u003e(b =\u003e b\n    .AppendPath(\"Project\")\n    .AppendPath(\"123\")\n    .FormValue(\"Test\", \"Value\")\n    .FormValue(\"key\", \"value\")\n    .QueryString(\"page\", 10)\n);\n```\n\nCustom authorization header\n\n```csharp\nvar client = new HttpClient();\nclient.BaseAddress = new Uri(\"https://api.github.com/\", UriKind.Absolute);\n\nvar result = await client.GetAsync\u003cRepository\u003e(b =\u003e b\n    .AppendPath(\"repos\")\n    .AppendPath(\"loresoft\")\n    .AppendPath(\"FluentRest\")\n    .Header(h =\u003e h.Authorization(\"token\", \"7ca...\"))\n);\n```\n\nUse with HttpClientFactory and Retry handler\n\n```csharp\nvar services = new ServiceCollection();\n\nservices.AddSingleton\u003cIContentSerializer, JsonContentSerializer\u003e();\nservices.AddHttpClient\u003cGithubClient\u003e(c =\u003e\n    {\n        c.BaseAddress = new Uri(\"https://api.github.com/\");\n\n        c.DefaultRequestHeaders.Add(\"Accept\", \"application/vnd.github.v3+json\");\n        c.DefaultRequestHeaders.Add(\"User-Agent\", \"GitHubClient\");\n    })\n    .AddHttpMessageHandler(() =\u003e new RetryHandler());\n\nvar serviceProvider = services.BuildServiceProvider();\n\nvar client = serviceProvider.GetService\u003cGithubClient\u003e();\nvar result = await client.GetAsync\u003cRepository\u003e(b =\u003e b\n    .AppendPath(\"repos\")\n    .AppendPath(\"loresoft\")\n    .AppendPath(\"FluentRest\")\n);\n```\n\n## Fake Response\n\n`FluentRest.Fake` package adds the ability to fake an HTTP responses by using a custom HttpClientHandler. Faking the HTTP response allows creating unit tests without having to make the actual HTTP call.\n\nTo install FluentRest.Fake, run the following command in the Package Manager Console\n\n    PM\u003e Install-Package FluentRest.Fake\n\n\n### Fake Response Stores\n\nFake HTTP responses can be stored in the following message stores.  To create your own message store, implement `IFakeMessageStore`.\n\n#### MemoryMessageStore\n\nThe memory message store allows composing a JSON response in the unit test.  Register the responses on the start of the unit test.\n\nRegister a fake response by URL.\n\n```csharp\nMemoryMessageStore.Current.Register(b =\u003e b\n    .Url(\"https://api.github.com/repos/loresoft/FluentRest\")\n    .StatusCode(HttpStatusCode.OK)\n    .ReasonPhrase(\"OK\")\n    .Content(c =\u003e c\n        .Header(\"Content-Type\", \"application/json; charset=utf-8\")\n        .Data(responseObject) // object to be JSON serialized\n    )\n);\n```\n\nUse the fake response in a unit test\n\n```csharp\nvar serializer = new JsonContentSerializer();\n\n// use memory store by default\nvar fakeHttp = new FakeMessageHandler();\n\nvar httpClient = new HttpClient(fakeHttp, true);\nhttpClient.BaseAddress = new Uri(\"https://api.github.com/\", UriKind.Absolute);\n\nvar client = new FluentClient(httpClient, serializer);\n\n// make HTTP call\nvar result = await client.GetAsync\u003cRepository\u003e(b =\u003e b\n    .AppendPath(\"repos\")\n    .AppendPath(\"loresoft\")\n    .AppendPath(\"FluentRest\")\n    .Header(h =\u003e h.Authorization(\"token\", \"7ca...\"))\n);\n```\n\nUse fake handlers with HttpClientFactory\n\n```csharp\nvar services = new ServiceCollection();\n\nservices.AddSingleton\u003cIContentSerializer, JsonContentSerializer\u003e();\nservices.AddSingleton\u003cIFakeMessageStore\u003e(s =\u003e MemoryMessageStore.Current);\n\nservices\n    .AddHttpClient\u003cEchoClient\u003e(c =\u003e c.BaseAddress = new Uri(\"http://httpbin.org/\"))\n    .AddHttpMessageHandler(s =\u003e new FakeMessageHandler(s.GetService\u003cIFakeMessageStore\u003e(), FakeResponseMode.Fake));\n\nvar serviceProvider = services.BuildServiceProvider();\n\n// fake response object\nvar response = new EchoResult();\nresponse.Url = \"http://httpbin.org/post?page=10\";\nresponse.Headers[\"Accept\"] = \"application/json\";\nresponse.QueryString[\"page\"] = \"10\";\nresponse.Form[\"Test\"] = \"Fake\";\nresponse.Form[\"key\"] = \"value\";\n\n// setup fake response\nMemoryMessageStore.Current.Register(b =\u003e b\n    .Url(\"http://httpbin.org/post?page=10\")\n    .StatusCode(HttpStatusCode.OK)\n    .ReasonPhrase(\"OK\")\n    .Content(c =\u003e c\n        .Header(\"Content-Type\", \"application/json; charset=utf-8\")\n        .Data(response)\n    )\n);\n\nvar client = serviceProvider.GetService\u003cEchoClient\u003e();\n\nvar result = await client.PostAsync\u003cEchoResult\u003e(b =\u003e b\n    .AppendPath(\"post\")\n    .FormValue(\"Test\", \"Fake\")\n    .FormValue(\"key\", \"value\")\n    .QueryString(\"page\", 10)\n).ConfigureAwait(false);\n```\n\n#### FileMessageStore\n\nThe file message store allows saving an HTTP call response on the first use.  You can then use that saved response for all future unit test runs.\n\n\nConfigure the FluentRest to capture response.\n\n```csharp\nvar serializer = new JsonContentSerializer();\n\n// use file store to load from disk\nvar fakeStore = new FileMessageStore();\nfakeStore.StorePath = @\".\\GitHub\\Responses\";\n\nvar fakeHttp = new FakeMessageHandler(fakeStore, FakeResponseMode.Capture);\n\nvar httpClient = new HttpClient(fakeHttp, true);\nhttpClient.BaseAddress = new Uri(\"https://api.github.com/\", UriKind.Absolute);\n\nvar client = new FluentClient(httpClient, serializer);\n\nvar result = await client.GetAsync\u003cRepository\u003e(b =\u003e b\n    .AppendPath(\"repos\")\n    .AppendPath(\"loresoft\")\n    .AppendPath(\"FluentRest\")\n    .Header(h =\u003e h.Authorization(\"token\", \"7ca...\"))\n);\n```\n\nUse captured response\n\n```csharp\nvar serializer = new JsonContentSerializer();\n\n// use file store to load from disk\nvar fakeStore = new FileMessageStore();\nfakeStore.StorePath = @\".\\GitHub\\Responses\";\n\nvar fakeHttp = new FakeMessageHandler(fakeStore, FakeResponseMode.Fake);\n\nvar httpClient = new HttpClient(fakeHttp, true);\nhttpClient.BaseAddress = new Uri(\"https://api.github.com/\", UriKind.Absolute);\n\nvar client = new FluentClient(httpClient, serializer);\n\nvar result = await client.GetAsync\u003cRepository\u003e(b =\u003e b\n    .AppendPath(\"repos\")\n    .AppendPath(\"loresoft\")\n    .AppendPath(\"FluentRest\")\n    .Header(h =\u003e h.Authorization(\"token\", \"7ca...\"))\n);\n```\n\n## Change Log\n\n### Version 6.0\n\n* [Breaking] Remove netstandard1.3 support\n* add overload for generic AppendPath\n* update dependence packages\n\n### Version 5.0\n\n* [Breaking] Major refactor to support HttpClientFactory\n* [Breaking] `FluentClient` changed to a light wrapper for `HttpClient`\n* [Breaking] Removed `FluentClient.BaseUri` defaults, use `HttpClient.BaseAddress` instead\n* [Breaking] Removed `FluentClient` default headers, use `HttpClient` instead\n* [Breaking] All fluent builder take `HttpRequestMessage` instead of `FluentRequest`\n* [Breaking] Removed `FluentRequest` and `FluentResponse` classes\n* [Breaking] Removed `FluentRequest.Create` fluent builder\n* [Breaking] Moved all Fake Response handlers to `FluentRest.Fake` Nuget Package\n* [Breaking] Removed interceptor support in favor of HttpClientFactory middleware handlers\n* Add support for HttpClientFactory typed client and middleware handlers\n* Add `FluentRequest.Factory` to support named FluentClient instances\n","funding_links":["https://github.com/sponsors/loresoft"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floresoft%2Ffluentrest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Floresoft%2Ffluentrest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floresoft%2Ffluentrest/lists"}