Coder Social home page Coder Social logo

lucassklp / rx.http Goto Github PK

View Code? Open in Web Editor NEW
69.0 4.0 8.0 2.32 MB

A reactive way to make HTTP Request in .NET Core ๐Ÿš€

License: MIT License

C# 100.00%
reactive-programming reactive-streams reactive http-client dotnet-core dotnet-core2 dotnet http rest-client csharp

rx.http's Introduction

nuget nuget version

A lightweight library that is inpired in Angular 2+ Http Client built on top of .NET Http Client that help programmers to make asynchronous http requests.

Installation

If you are using Package Manager:

Install-Package Rx.Http -Version 2.0.3

If you are using .NET CLI

dotnet add package Rx.Http --version 2.0.3

Example of use

using Rx.Http;
using System.Reactive.Linq;

public class Program
{
    public static async void Main()
    {
        //Initialize the RxHttpClient
        var http = RxHttpClient.Create();

        //Retrieve a list of To-Do item and print the title of each element asynchronously
        http.Get<List<Todo>>("https://jsonplaceholder.typicode.com/todos/").Subscribe(items => {
            items.ForEach(item => Console.WriteLine(item.title));
        });

        //Making the same request using await
        List<Todo> response = await http.Get<List<Todo>>("https://jsonplaceholder.typicode.com/todos/");
    }
}

Options

You can setup your request by using options. It make possible you set query strings, headers and your custom serializer and deserializer for your request and response.

Let's dive in options

http.Get<List<Todo>>("https://jsonplaceholder.typicode.com/todos/", options =>
{
    options.AddHeader(new {
            Authorization = "Bearer <token>"
            Accept = "application/json"
        })
        .AddQueryString(new {
            name = "John Doe",
            index = 1
        });
});

HttpMediaType

The media type represents a interface that is used to translate a mime type to a object (serializing and deserializing).

It's called when you provide a type when you call a request like that:

var url = "https://myapi.com/names/";
var parameters = new 
{
    Name = "Lucas"
};
http.Post<List<string>>(url, parameters)
//       ^^^^^^^^^^^^^

In this example, you're sending an object which contains a property "Name" and a value "Lucas" and you're expecting to receive a List<string> from server.

Suppose that the server only does accept XML and reply the request using the CSV format. So, we have to convert the "parameter" object to XML and convert the server reply to List<string> right? That's why we have the interfaces IHttpMediaTypeSerializer and IHttpMediaTypeDeserializer.

You could create XmlHttpMediaType and CsvHttpMediaType which implements IHttpMediaTypeSerializer and IHttpMediaTypeDeserializer to solve this issue. The final code would be like that.

var url = "https://myapi.com/names/";
var parameters = new 
{
    Name = "Lucas"
};
http.Get<List<string>>(url, parameters, options =>
{
    options.SetRequestMediaType(new XmlHttpMediaType())
        .SetResponseMediaType(new CsvHttpMediaType())
});

RequestMediaType is used to serialize your body content when you are making a request. It's only called when you provide type on Generic. By default is used JsonHttpMediaType

ResponseMediaType is used to deserialize the response from server. By default is used JsonHttpMediaType

Consumers

A consumer is defined as a service that have common behavior for the requests. You can encapsulate the logic of all those requests in a easy way. The main advantage of using consumers is to abstract the HTTP request and its implementation details, and only work with the results from it. The concept is very similar to FeignClient interface from Spring Cloud

Interceptors

The interceptors are a pre-processing unit that changes the request before it happens. It can be usefull set a standard for all requests.

Example of use

In this example, we need to provide the api key for all requests to The Movie Database API

The code above shows how to use Consumers and Interceptors.

    public class TheMovieDatabaseConsumer : RxHttpClient
    {
        public TheMovieDatabaseConsumer(HttpClient httpClient): base(httpClient, null)
        {
            httpClient.BaseAddress = new Uri(@"https://api.themoviedb.org/3/");
            RequestInterceptors.Add(new TheMovieDatabaseInterceptor());
        }

        public IObservable<Movies> ListMovies() => Get<Movies>("movie/popular");
    }

    internal class TheMovieDatabaseInterceptor : RxRequestInterceptor
    {
        public void Intercept(RxHttpRequestOptions request)
        {
            request.AddQueryString("api_key", "eb7b25db28349bd4eef1498a5be9842f");
        }
    }

RxHttpRequestException

This exception is threw when the server reply with a HTTP Status different of 2xx. There's two ways to handle this exception:

    var url = @"https://jsonplaceholder.typicode.com/this_page_dont_exist_hehehe/";

    //With traditional try-catch block
    try
    {
        var todos = await http.Get<List<Todo>>(url);
    }
    catch(RxHttpRequestException ex)
    {
        HttpResponseMessage response = ex.Response;
        //...
    }

    //Or using reactive way
    http.Get<List<Todo>>(url).Subscribe(response =>
    {
        //...
    }, exception =>
    {
        HttpResponseMessage response = (exception as RxHttpRequestException)?.Response;
        //...
    })

Working with Dependency Injection

Is strongly recommended to use DI (Dependency Injection) with Rx.Http, because of HttpClientFactory, that improves HttpClient performance. For that, you must do the following:

public void ConfigureServices(ServiceCollection services)
{
    services.UseRxHttp();
    services.AddSingleton<JsonPlaceHolderConsumer>();
}

Logging

You can implement your own custom logging mechanism by implementing the interface RxHttpLogger. We provide a built-in logging mechanism called "RxHttpDefaultLogger". In case you don't have Microsoft.Extensions.Logging added on your project you can use RxHttpConsoleLogger

Here is a example that show how to use RxHttpDefaultLogger mechanism. If you have a custom logging mechanism you must replace RxHttpDefaultLogging for your class implementation.

private static void ConfigureServices(ServiceCollection services)
{
    services.AddRxHttpLogger<RxHttpDefaultLogger>();
}

Global Settings

You can setup default settings by setting the RxHttp.Default like the example below:

RxHttp.Default.RequestMediaType = new JsonHttpMediaType(new NewtonsoftJsonSerializer());
RxHttp.Default.ResponseMediaType = new JsonHttpMediaType(new NewtonsoftJsonSerializer())

Save response to file (Download)

You can also download a file using Rx.Http with a code like that:

var fileName = $"mysql-installer-web-community-8.0.22.0.msi";
var directory = Directory.GetCurrentDirectory();
var path = Path.Combine(directory, fileName);
await http.Get($@"https://dev.mysql.com/get/Downloads/MySQLInstaller/{fileName}")
    .ToFile(path); // Save response to path (download)

Navigator

The navigator works like a RxHttpClient, but it manage cookies automatically. This is useful when you want to keep session information when you make your requests. Suppose that mysite handles the session with cookies and you want to keep your session, so you can do like that:

var navigator = RxNavigator.Create();
navigator.Post("https://www.mysite.com/login", new 
{
    Login = "myLogin",
    Password = "myPass"
});

navigator.Post("https://www.mysite.com/create/task", new 
{
    Title = "myTitle",
    Description = "myDescription",
    Date = DateTime.Now
});

Note that you did nothing about cookies but could call the endpoint to create a new task using this session.

Convert to HTML Document

Suppose that you need to get a specific value from a HTML Element (for example, a label, a link or a div). Rx.Http is integrated with HtmlAgilityPack.NetCore. It can be done by calling the Extension Method called AsHtmlDocument().

๐Ÿ”ฅ Pro Tip: It can be used with RxNavigator to automatize some tasks!

Roadmap

Version 1.x

  • Reactive GET, POST, PUT DELETE Http Methods
  • Built-in JSON serializing and deserializing (using Newtonsoft.Json)
  • Support for custom serializing and deserializing
  • Logging
  • Consumers and Interceptors implementation
  • Error handling
  • Native support for x-www-form-urlencoded and form-data

Version 2.x

  • Global settings
  • ASP.Net Core native integration (Dependency Injection)
  • Save response to file (download)
  • Provide a alternative for built-in Json serializer: System.Text.Json.JsonSerializer of .NET Core 3
  • Implement cancellation token funcionality

rx.http's People

Contributors

lucassklp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

rx.http's Issues

Shortcut for add Headers and Query String

It could be like:

AddHeader(new Dictionary<string, string>(){
{"key1": "value1"},
{"key2": val}
//...
});

Or simply:

AddHeader(new {
key1: "value1",
key2: "value2"
})

Create wiki pages

Content:

  • Core concepts
  • Getting Started
  • Consumers
  • Interceptors
  • HttpMediaType
  • Navigator
  • Features
  • Logging
    • Save to file
    • Reading response as HtmlDocument
    • Reading response as String

Tips:

  • How to use Rx.Http to Extact data from webpages
  • How to automatize your work with Rx.Http
  • How Rx.Http can be used to automatize tests of WebAPI and Webpages

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.