{"id":32958219,"url":"https://github.com/Notorious-Coding/Notorious-Client","last_synced_at":"2025-11-16T17:01:59.400Z","repository":{"id":190699343,"uuid":"659726453","full_name":"Notorious-Coding/Notorious-Client","owner":"Notorious-Coding","description":null,"archived":false,"fork":false,"pushed_at":"2025-10-26T11:04:23.000Z","size":157,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-10-26T12:29:52.608Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/Notorious-Coding.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-06-28T12:34:04.000Z","updated_at":"2025-10-26T11:04:27.000Z","dependencies_parsed_at":"2024-01-17T19:20:43.093Z","dependency_job_id":"44644db2-0a71-4c5a-abf6-2f3740957f8b","html_url":"https://github.com/Notorious-Coding/Notorious-Client","commit_stats":null,"previous_names":["notorious-coding/notorious-client"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/Notorious-Coding/Notorious-Client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Notorious-Coding%2FNotorious-Client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Notorious-Coding%2FNotorious-Client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Notorious-Coding%2FNotorious-Client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Notorious-Coding%2FNotorious-Client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Notorious-Coding","download_url":"https://codeload.github.com/Notorious-Coding/Notorious-Client/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Notorious-Coding%2FNotorious-Client/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":284742551,"owners_count":27056072,"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","status":"online","status_checked_at":"2025-11-16T02:00:05.974Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2025-11-12T23:00:34.015Z","updated_at":"2025-11-16T17:01:59.393Z","avatar_url":"https://github.com/Notorious-Coding.png","language":"C#","funding_links":[],"categories":["HTTP"],"sub_categories":["GUI - other"],"readme":"## ![Logo](./Documentation/Images/NotoriousClient.png)\n\n**Notorious Client** is meant to simplify the sending of HTTP requests through a fluent builder and an infinitely extensible client system.\n\n[![NuGet](http://img.shields.io/nuget/vpre/NotoriousClient.svg?label=NuGet)](https://www.nuget.org/packages/NotoriousClient/)\n\n## Summary\n\n- [Support](#support)\n- [Features](#features)\n- [Motivation](#motivation)\n- [Getting started](#getting-started)\n- [How could i use RequestBuilder ?](#how-could-i-use-requestbuilder)\n- [How could i implement a custom BaseClient](#how-could-i-implement-a-custom-baseclient)\n- [How could i use requestBuilder in Standalone ?](#how-can-i-use-the-requests-builder-in-standalone)\n\n## Support\n\n- .NET 8+\n\n## Features\n\n- Easy building of HttpRequestMessage\n- Easy building of multipart/form-data requests\n- Body serialisation as JSON, powered by System.Text.Json, but customisable.\n- Easy handling of request's authentication\n- Infinitely extensible system.\n- Allow you to build maintanable and testable API Client.\n\n## Motivation\n\nThe goal is to provide a way to create API clients that is clear, fast, and above all, maintainable.\n\n## Getting Started\n\nFirst, [install NuGet](http://docs.nuget.org/docs/start-here/installing-nuget). Then, install [NotoriousClient](https://www.nuget.org/packages/NotoriousClient/) from the package manager console:\n\n```\nPM\u003e Install-Package NotoriousClient\n```\n\nOr from the .NET CLI as:\n\n```\ndotnet add package NotoriousClient\n```\n\nThen create a client, and inherit from BaseClient :\n\n```csharp\nusing NotoriousClient.Clients;\n\npublic class UserClient : BaseClient, IUserClient\n{\n    public UserClient(IRequestSender sender, string url) : base(sender, url)\n    {\n    }\n}\n```\n\nAdd method within that client that uses RequestBuilder to build your request.\n\n```csharp\npublic class UserClient : BaseClient, IUserClient\n{\n    // Define your endpoint\n    private Endpoint GET_USERS_ENDPOINT = new Endpoint(\"/api/users\", Method.Get);\n\n    public UserClient(IRequestSender sender, string url) : base(sender, url)\n    {\n    }\n\n    // Add call method.\n    public async Task\u003cIEnumerable\u003cUser\u003e\u003e GetUsers()\n    {\n        HttpRequestMessage request = GetBuilder(GET_USERS_ENDPOINT)\n            .WithAuthentication(\"username\", \"password\")\n            .AddQueryParameter(\"limit\", \"100\")\n            .Build();\n\n        HttpResponseMessage response = await Sender.SendAsync(request);\n\n        return response.ReadAs\u003cIEnumerable\u003cUser\u003e\u003e();\n    }\n}\n\n```\n\nOther example of API call.\n\n```csharp\nprivate Endpoint GET_USER_ENDPOINT = new Endpoint(\"/api/users/{id}\", Method.Get);\n\npublic async Task\u003cUser\u003e GetUser(int id)\n{\n    HttpRequestMessage request = GetBuilder(GET_USERS_ENDPOINT)\n        .WithAuthentication(\"username\", \"password\")\n        .AddEndpointParameter(\"id\", id.ToString())\n        .Build();\n\n    HttpResponseMessage response = await Sender.SendAsync(request);\n\n    return response.ReadAs\u003cUser\u003e();\n}\n```\n\n```csharp\nprivate Endpoint CREATE_USER_ENDPOINT = new Endpoint(\"/api/users\", Method.Post);\n\npublic async Task\u003cUser\u003e CreateUser(User user)\n{\n    HttpRequestMessage request = GetBuilder(CREATE_USER_ENDPOINT)\n        .WithAuthentication(\"username\", \"password\")\n        .WithJsonBody(user)\n        .Build();\n\n    HttpResponseMessage response = await Sender.SendAsync(request);\n\n    return response.ReadAs\u003cUser\u003e();\n}\n```\n\nLast but not least, add everything to your dependency injection.\n\n```csharp\nservices.AddHttpClient();\nservices.AddScoped\u003cIRequestSender\u003e((serviceProvider) =\u003e new RequestSender(serviceProvider.GetRequiredService\u003cIHttpClientFactory\u003e()));\nservices.AddScoped((serviceProvider) =\u003e new UserClient(serviceProvider.GetRequiredService\u003cIRequestSender\u003e(), \"http://my.api.com/\"));\n```\n\n## How could i use RequestBuilder ?\n\nLets dive into the possibity of the RequestBuilder !\n\n### Configure URN, URL, and http verb.\n\n```csharp\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get);\n```\n\nOr with `Endpoint` class :\n\n```csharp\nEndpoint endpoint = new Endpoint(\"/users\", Method.Get);\nnew RequestBuilder(\"https://toto.com\", endpoint);\n```\n\nor with `VersionedEndpoint` class :\n\n```csharp\nVersionedEndpoint endpoint = new VersionedEndpoint(\"/users\", Method.Get, \"v1.0\");\nnew RequestBuilder(\"https://toto.com/api\", endpoint); // Will result in \"https://toto.com/api/v1.0/users\"\n```\n\n\n### Configure URI parameters\n\n**Add URL parameters**\n\n```csharp\nnew RequestBuilder(\"https://toto.com\", \"/users/{id}\", Method.Get).AddEndpointParameter(\"id\", \"myfakeid\");\n\n```\n\n```csharp\nIDictionary\u003cstring, string\u003e endpointsParams = ...;\nnew RequestBuilder(\"https://toto.com\", \"/users/{id}/{name}\", Method.Get).AddEndpointParameters(endpointsParams);\n```\n\n**Add Query Parameters**\n\n```csharp\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).AddQueryParameter(\"id\", \"myfakeid\");\n\n```\n\n```csharp\nIDictionary\u003cstring, string\u003e queryParams = ...;\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).AddQueryParameters(queryParams);\n```\n\n### Configure request's headers\n\n**Add custom headers**\n\n```csharp\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).AddCustomHeader(\"id\", \"myfakeid\");\n\n```\n\n```csharp\nIDictionary\u003cstring, string\u003e headers = ...;\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).AddCustomHeaders(headers);\n```\n\n**Add accept header**\n\n```csharp\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).WithCustomAcceptMediaType(\"application/json\");\n\n```\n\n### Authentication\n\n**Add basic authentication**\n\n```csharp\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).WithAuthentication(\"login\", \"password\");\n\n```\n\n**Add bearer authentication**\n\n```csharp\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).WithAuthentication(\"token\");\n\n```\n\n**Add custom scheme authentication**\n\n```csharp\npublic class NotoriousAuthentication : IAuthenticationInformation\n{\n    private readonly string _crownId;\n    private readonly string _crownName;\n    public NotoriousAuthentication(string crownId, string crownName)\n    {\n        _crownId = crownId;\n        _crownName = crownName;\n    }\n\n    public string Token =\u003e _crownName + _crownId;\n\n    public string Scheme =\u003e \"Notorious\";\n}\n\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).WithAuthentication(new NotoriousAuthentication(\"1997\", \"BIG\"));\n```\n\n### Add body to classic request\n\n**Add body as JSON**\n\n```csharp\nUser user = GetUsersFromDb()\n\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).WithJsonBody(user);\n\n```\n\n**Add body as JSON with a custom serializer**\n\n```csharp\n\npublic class CustomSerializer : IJsonSerializer\n{\n    public string ConvertToJson(object obj)\n    {\n        // Your serilization logic here...\n    }\n}\n\nUser user = GetUsersFromDb()\n\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).WithJsonBody(user, new CustomSerializer());\n\n```\n\n**Add body as Stream**\n\n```csharp\nStream stream = GetFileStream(\"C:/Crown/BIG.png\")\n\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).WithStreamBody(stream);\n\n```\n\n**Add body as HTTP Content**\n\n```csharp\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).WithContentBody(new StringContent(\"MyCustomContent\"));\n```\n\n\u003e :warning: Note that you could use any type of content handled by .NET, such as StringContent, StreamContent, HttpContent, etc...\n\n### Add body to multipart request\n\n\u003e :warning: Note that you CAN'T use multipart bodies if you already added a classic body to the request\n\n**Add body as JSON**\n\n```csharp\nUser user = GetUsersFromDb()\n\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).WithJsonMultipartBody(user, \"USER_SECTION\");\n\n```\n\n**Add body as JSON with a custom serializer**\n\n```csharp\n\npublic class CustomSerializer : IJsonSerializer\n{\n    public string ConvertToJson(object obj)\n    {\n        // Your serilization logic here...\n    }\n}\n\nUser user = GetUsersFromDb()\n\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).WithJsonMultipartBody(user, \"USER_SECTION\", new CustomSerializer());\n\n```\n\n**Add body as Stream**\n\n```csharp\nStream stream = GetFileStream(\"C:/Crown/BIG.png\")\n\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).WithStreamMultipartBody(stream, \"STREAM_SECTION\");\n\n```\n\n**Add body as HTTP Content**\n\n```csharp\nnew RequestBuilder(\"https://toto.com\", \"/users\", Method.Get).WithContentMultipartBody(new StringContent(\"MyCustomContent\"), \"CUSTOM_CONTENT_SECTION\");\n```\n\n## How could i implement a custom BaseClient ?\n\n**NotoriousClient** is entirely designed to be infinitely extensible.\n\nLet's say you need to get a token from an API before every request.\n\n```csharp\npublic class BearerAuthClient : BaseClient\n{\n    private readonly ITokenClient _tokenClient;\n\n    public BearerAuthClient(IRequestSender sender, string url, ITokenClient tokenClient) : base(sender, url)\n    {\n        ArgumentNullException.ThrowIfNull(tokenClient, nameof(tokenClient));\n        _tokenClient = tokenClient;\n    }\n\n    protected override async Task\u003cIRequestBuilder\u003e GetBuilderAsync(string route, Method method = Method.Get)\n    {\n        // Get your token every time you create a request.\n        string token = await GetToken();\n\n        // Return a preconfigured builder with your token !\n        return (await base.GetBuilderAsync(route, method)).WithAuthentication(token);\n    }\n\n    public async Task\u003cstring\u003e GetToken()\n    {\n        // Handle token logic here.\n        return await _tokenClient.GetToken();\n    }\n}\n\npublic class UserClient : BearerAuthClient\n{\n    private Endpoint CREATE_USER_ENDPOINT = new Endpoint(\"/api/users\", Method.Post);\n\n    public UserClient(IRequestSender sender, string url) : base(sender, url)\n    {\n    }\n\n    public async Task\u003cIEnumerable\u003cUser\u003e\u003e CreateUser(User user)\n    {\n        // Every builded request will be configured with bearer authentication !\n        HttpRequestMessage request = (await GetBuilderAsync(CREATE_USER_ENDPOINT))\n            .WithJsonBody(user)\n            .Build();\n\n        HttpResponseMessage response = await Sender.SendAsync(request);\n\n        return response.ReadAs\u003cUser\u003e();\n    }\n}\n```\n\nThis is your turn to play with it, you could image everything you want, adding custom authentication, custom company headers, logging !\n\n## How can i use the request's builder in standalone ?\n\nYou can create a standalone builder by instantiating RequestBuilder.\n\n```csharp\n\n// Dont forget to use IRequestBuilder to have access to extensions method !\nIRequestBuilder requestBuilder = new RequestBuilder(\"http://my.api.com/\", \"api/v1.0/users\", Method.GET);\n\n```\n\nThen, you will have access to all same method that you were using in Client !\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNotorious-Coding%2FNotorious-Client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FNotorious-Coding%2FNotorious-Client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNotorious-Coding%2FNotorious-Client/lists"}