Nexar is a lightweight and ergonomic HTTP client for .NET. It offers static helpers, a fluent request builder, typed responses, and first-class support for common web API needs.
- Static Methods:
Nexar.Get<T>(),Nexar.Post<T>(),Nexar.Put<T>(),Nexar.Delete<T>(),Nexar.Patch<T>(),Nexar.Head<T>() - Instance API:
Nexar.Create()plusGetAsync<T>(),PostAsync<TRequest, TResponse>(), and more - Fluent Builder: Chain headers, query parameters, and body configuration
- Typed Responses:
NexarResponse<T>withData,Status,Headers,RawContent - Content Types: JSON, form URL encoded, multipart form data, binary
- Interceptors: Request, response, and error hooks
- Retries: Optional retries with exponential backoff
- Authentication Helpers: Bearer token, Basic auth, API key helpers
dotnet add package BuzzSpire.NexarusingNexar;usingNexar.Configuration;usingNexar.Models;varresponse=awaitNexar.Get<User>("https://api.example.com/users/1");if(response.IsSuccess&&response.Data!=null){Console.WriteLine(response.Data.Name);Console.WriteLine($"Status: {response.Status}");}// Need raw text? Use string as the response type.varraw=awaitNexar.Get<string>("https://api.example.com/users/1");Console.WriteLine(raw.Data??raw.RawContent);varapi=Nexar.Create(newNexarConfig{BaseUrl="https://api.example.com",DefaultHeaders=newDictionary<string,string>{{"Accept","application/json"},{"User-Agent","Nexar/1.0"}},TimeoutMs=30_000,MaxRetryAttempts=3});varuser=awaitapi.GetAsync<User>("/users/1");varresponse=awaitNexar.Create().Request().Url("https://api.example.com/search").WithHeader("Accept","application/json").WithQuery("q","nexar").WithQuery("limit",10).GetAsync<SearchResults>();varresponse=awaitNexar.Request<User>(newRequestOptions{Method="POST",Url="/users",BaseURL="https://api.example.com",Headers=newDictionary<string,string>{{"Authorization","Bearer token"}},Data=new{Name="John"},ContentType=ContentType.Json,Timeout=5_000,MaxRetries=2,ValidateSsl=true});varresponse=awaitNexar.Get<User>("/users/1");Console.WriteLine(response.Data);// Deserialized objectConsole.WriteLine(response.Status);// HTTP status codeConsole.WriteLine(response.StatusText);// Status messageConsole.WriteLine(response.Headers);// Response headersConsole.WriteLine(response.IsSuccess);// true/falseConsole.WriteLine(response.RawContent);// Raw response bodyvarformData=newDictionary<string,object>{{"title","My Document"},{"file",fileBytes}};varresponse=awaitapi.PostAsync<Dictionary<string,object>,string>("/upload",null,formData,ContentType.FormData);Available Content Types:
ContentType.JsonContentType.FormUrlEncodedContentType.FormDataContentType.Binary
publicclassLoggingInterceptor:IInterceptor{publicTask<HttpRequestMessage>OnRequestAsync(HttpRequestMessagerequest){Console.WriteLine($"-> {request.Method}{request.RequestUri}");returnTask.FromResult(request);}publicTask<HttpResponseMessage>OnResponseAsync(HttpResponseMessageresponse){Console.WriteLine($"<- {response.StatusCode}");returnTask.FromResult(response);}publicTaskOnErrorAsync(Exceptionexception){Console.WriteLine($"Error: {exception.Message}");returnTask.CompletedTask;}}varapi=Nexar.Create();api.Interceptors.Add(newLoggingInterceptor());varresponse=awaitNexar.Create().Request().Url("/protected").WithBearerToken("your-jwt-token").GetAsync<Data>();varapi=Nexar.Create(newNexarConfig{MaxRetryAttempts=3,RetryDelayMilliseconds=1000,UseExponentialBackoff=true});- Samples:
samples - Getting Started:
docs/GetStarted.md
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License.