Skip to content

Commit

Permalink
Merge pull request #71 from jgiacomini/develop
Browse files Browse the repository at this point in the history
Merge 1.6.0
  • Loading branch information
jgiacomini authored Oct 27, 2018
2 parents 934060e + 342c679 commit 11f372a
Show file tree
Hide file tree
Showing 24 changed files with 734 additions and 98 deletions.
87 changes: 58 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,56 +5,46 @@
[![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/Tiny-RestClient/Lobby)
[![StackOverflow](https://img.shields.io/badge/questions-on%20StackOverflow-orange.svg?style=flat)](http://stackoverflow.com/questions/tagged/tiny.restclient)

[Please visit the main site.](https://jgiacomini.github.io/Tiny.RestClient/)

Tiny.RestClient facilitates the dialog between your API and your application.
It hides all the complexity of communication, deserialisation ...


## Platform Support
|Platform|Supported|Version|Dependencies|Feature not supported|
| ------------------- | :-----------: | :------------------: | :------------------: |:------------------: |
|.NET Standard|Yes|1.1 && 1.2|Use System.Xml.XmlSerializer and Newtonsoft.Json|Manipulate files|
|.NET Standard|Yes|1.3|Use System.Xml.XmlSerializer and Newtonsoft.Json|-|
|.NET Standard|Yes|2.0|Use Newtonsoft.Json|-|
|.NET Framework|Yes|4.5+|Use Newtonsoft.Json|-|
|.NET Framework|Yes|4.6+|Use Newtonsoft.Json|-|
|.NET Framework|Yes|4.7+|Use Newtonsoft.Json|-|

The support of .NET Standard 1.1 to 2.0 allow you to use it in :
- .Net Framework 4.6+
- Xamarin iOS et Android

The support of **.NET Standard 1.1 to 2.0** allow you to use it in :
- .Net Framework 4.5+
- Xamarin iOS, Xamarin Android
- .Net Core
- UWP
- Windows Phone 8.1
- Windows 8.1

## Features
* Modern async http client for REST API.
* Support of verbs : GET, POST , PUT, DELETE, PATCH
* Support of custom http verbs
* Support of verbs : GET, POST , PUT, DELETE, PATCH and custom http verbs
* Support of ETag
* Support of multi-part form data
* Support of cancellation token on each requests
* Support of : download file and Upload file
* Automatic XML and JSON serialization / deserialization
* Support of custom serialisation / deserialisation
* Support of camelCase, snakeCase kebabCase for json serialization
* Support of multi-part form data
* Download file
* Upload file
* Support of gzip/deflate (compression and decompression)
* Optimized http calls
* Support of compression and decompression (gzip and deflate)
* Typed exceptions which are easier to interpret
* Define timeout globally or by request
* Timeout exception throwed if the request is in timeout (by default HttpClient send OperationCancelledException, so we can't make difference between a user annulation and timeout)
* Define timeout globally or per request
* Timeout exception thrown if the request is in timeout (by default HttpClient sends OperationCancelledException, so we can't distinguish between user cancellation and timeout)
* Provide an easy way to log : all sending of request, failed to get response, and the time get response.
* Support of export requests to postman collection
* Support of display cURL request in debug output
* Support of display cURL requests in debug output
* Support of Basic Authentification
* Support of OAuth2 Authentification


## Basic usage

### Create the client

Define a global timeout for all client. (By default it's setted to 100 secondes)
```cs
using Tiny.RestClient;

Expand Down Expand Up @@ -171,8 +161,8 @@ var response = await client.
```

### Define timeout
Define a global timeout for all client. (By default it's setted to 100 secondes)

Define global timeout
```cs
client.Settings.DefaultTimeout = TimeSpan.FromSeconds(100);
```
Expand Down Expand Up @@ -211,7 +201,7 @@ string response = await client.
// GET http://MyAPI.com/api/City/All with from url encoded content
```

## multi-part form data
## Multi-part form data

```cs
// With 2 json content
Expand Down Expand Up @@ -257,21 +247,44 @@ var response = await client.
AddFileContent(fileInfo1, "text/plain").
AddFileContent(fileInfo2, "text/plain").
ExecuteAsync<Response>();


// With 2 strings content
var response = await client.
PostRequest("City/Image/Text").
AsMultiPartFromDataRequest().
AddString("string1", "text/plain").
AddString("string2", "text/plain").
ExecuteAsync<Response>();

// With mixed content
await client.PostRequest("MultiPart/Test").
await client.PostRequest("Files/Add").
AsMultiPartFromDataRequest().
AddContent<City>(city1, "city1", "city1.json").
AddByteArray(byteArray1, "request", "request2.bin").
AddStream(stream2, "request", "request2.bin")
AddString("string1", "text", "request.txt")
ExecuteAsync();
```


## Streams and bytes array
You can use as content : streams or byte arrays.
## String, Streams and bytes array
You can use as content : strings, streams or byte arrays.
If you use these methods no serializer will be used.

### String
```cs
// Read string response
Stream stream = await client.
GetRequest("text").
ExecuteAsStringAsync();

// Post String as content
await client.PostRequest("poetry/text").
AddStringContent(stream).
ExecuteAsync();
```

### Streams
```cs
// Read stream response
Expand Down Expand Up @@ -327,6 +340,22 @@ catch (HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.Intern
throw new ServerErrorException($"{ex.Message} {ex.ReasonPhrase}");
}
```
## ETag
The lib support the Entity tag but it's not enabled by default.

### Define an ETagContainer globally
An implementation of IETagContainer is provided. It stores all data in multiples files.

To enable it :
```cs
client.Settings.ETagContainer = new ETagFileContainer(@"C:\ETagFolder");
```

### Define an ETagContainer for one request
You can also define the ETagContainer only on specific request.
```cs
request.WithETagContainer(eTagContainer);
```

## Formatters

Expand Down
17 changes: 17 additions & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
# Release notes
## 1.6.0
* Add support of Entity Tag (ETag)

ETag is not enabled by default to enable it :
```cs
client.Settings.ETagContainer = new ETagFileContainer(@"C:\ETagFolder");
```
You can also enable on only on specific request like below :
```cs
request.WithETagContainer(eTagContainer);
```
* Add support of string content (for mono part and multipart requests)
```cs
request.AddStringContent("myContent").ExecuteAsycnc();
```
* Now the assembly is strong named

## 1.5.5
* Fix a bug on cURL listener (when body was null) the cURL request wasn't displayed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public async Task<string> One()
}

[HttpGet("GetPdf")]
public IActionResult Download()
public IActionResult GetPdf()
{
return File("pdf-sample.pdf", "application/pdf", "pdf-sample");
}
Expand Down
77 changes: 77 additions & 0 deletions Tests/Tiny.RestClient.ForTest.Api/Middleware/ETagMiddleware.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Net.Http.Headers;
using System.IO;
using System.Security.Cryptography;
using System.Threading.Tasks;

namespace Tiny.RestClient.ForTest.Api.Middleware
{
public class ETagMiddleware
{
private readonly RequestDelegate _next;

public ETagMiddleware(RequestDelegate next)
{
_next = next;
}

public async Task InvokeAsync(HttpContext context)
{
var response = context.Response;
using (var ms = new MemoryStream())
{
if (IsETagSupported(response))
{
var originalStream = response.Body;
string checksum = CalculateChecksum(ms);

response.Headers[HeaderNames.ETag] = checksum;

if (context.Request.Headers.TryGetValue(HeaderNames.IfNoneMatch, out var etag) && checksum == etag)
{
response.StatusCode = StatusCodes.Status304NotModified;
response.Body = ms;
await _next(context);
return;
}

await _next(context);
}
else
{
await _next(context);
}
}
}

private static bool IsETagSupported(HttpResponse response)
{
if (response.StatusCode != StatusCodes.Status200OK)
{
return false;
}

if (response.Headers.ContainsKey(HeaderNames.ETag))
{
return false;
}

return true;
}

private static string CalculateChecksum(MemoryStream ms)
{
string checksum = string.Empty;

using (var algo = SHA1.Create())
{
ms.Position = 0;
byte[] bytes = algo.ComputeHash(ms);
checksum = $"\"{WebEncoders.Base64UrlEncode(bytes)}\"";
}

return checksum;
}
}
}
1 change: 1 addition & 0 deletions Tests/Tiny.RestClient.ForTest.Api/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env)
}

app.UseMiddleware<CompressionMiddleware>();
app.UseMiddleware<ETagMiddleware>();
app.UseResponseCompression();
app.UseMvc();
}
Expand Down
8 changes: 8 additions & 0 deletions Tests/Tiny.RestClient.Tests/BaseTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ public static TinyRestClient GetClient()
return _client;
}

public static string ServerUrl
{
get
{
return _serverUrl;
}
}

public static TinyRestClient GetNewClient()
{
return GetNewClient(_serverUrl);
Expand Down
Loading

0 comments on commit 11f372a

Please sign in to comment.