Class HttpRestServiceClient<TClient>
To abstract the HttpClient implementation and optimize all HTTP Rest calls, this package has been created.
This is the main class that should be used whenever the need arises for an HTTP Rest call.
note
Follow the examples in this documentation to understand how to implement.
Inheritance
Implements
Inherited Members
Namespace: StoneCo.Framework.Services.Client
Assembly: cs.temp.dll.dll
Syntax
public sealed class HttpRestServiceClient<TClient> : IHttpRestServiceClient where TClient : class
Type Parameters
Name | Description |
---|---|
TClient | Concrete class of the connectors or clients provided by Domains or Microservices that implement the TService. |
Constructors
HttpRestServiceClient(IOptionsSnapshot<CommunicationLogOptions>, IHttpClientFactory, IConfiguration)
Default constructor to set the options and factory of the HttpClient.
Declaration
public HttpRestServiceClient(IOptionsSnapshot<CommunicationLogOptions> options, IHttpClientFactory httpClientFactory, IConfiguration configuration)
Parameters
Type | Name | Description |
---|---|---|
IOptionsSnapshot<CommunicationLogOptions> | options | The options design pattern used in HttpRestServiceClient. |
IHttpClientFactory | httpClientFactory | A factory abstraction for a component that can create HttpClient instances with custom configuration for a given logical name. |
IConfiguration | configuration | Represents a set of key/value application configuration properties. |
Examples
For a better application of the example, let's create a sample .NET Core API to use as a basis for this example.
note
You can also use this example to create a microservice client or a domain client.
Following the order of precedence and dependencies, let's start with the messages, which are used on the client and should be made available via NuGet.
FooMessage to default Foo information.
public class FooMessage
{
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("description")]
public string Description { get; set; }
}
NewFooMessageRequest to use on create new a Foo entry.
public class NewFooMessageRequest : RequestMessage
{
[JsonPropertyName("foo")]
public FooMessage FooMessage { get; set; }
}
NewFooMessageResponse with the result of creating Foo.
public class NewFooMessageResponse : ResponseMessage
{
[JsonPropertyName("id")]
public int FooId { get; set; }
[JsonPropertyName("foo")]
public FooMessage FooMessage { get; set; }
[JsonPropertyName("createdAt")]
public DateTime CreatedAt { get; set; }
}
UpdateFooMessageRequest to use on change a Foo entry.
public class UpdateFooMessageRequest : RequestMessage
{
[BindProperty(Name = "id")]
public int FooId { get; set; }
[FromBody, DataMember(Name = "foo")]
public FooMessage FooMessage { get; set; }
}
UpdateFooMessageResponse with the result of changing Foo.
public class UpdateFooMessageResponse : ResponseMessage
{
[JsonPropertyName("id")]
public int FooId { get; set; }
[JsonPropertyName("foo")]
public FooMessage FooMessage { get; set; }
[JsonPropertyName("updatedAt")]
public DateTime UpdatedAt { get; set; }
}
DeleteFooMessageRequest to use on delete a Foo entry.
public class DeleteFooMessageRequest : RequestMessage
{
[BindProperty(Name = "id")]
public int FooId { get; set; }
}
GetFooMessageRequest to use on get a Foo entry.
public class GetFooMessageRequest : RequestMessage
{
[BindProperty(Name = "id")]
public int FooId { get; set; }
}
FooMessageResponse with the result of Foo.
public class FooMessageResponse : ResponseMessage
{
[JsonPropertyName("foo")]
public FooMessage FooMessage { get; set; }
}
The next step is create a controller with APIs.
In the controller sample, we will use the sample messages above.
FooController with endpoints represented by the verbs GET, POST, PUT and DELETE.
[Route("api/foo"), Produces("application/json")]
public class FooController : Controller
{
public FooController() { }
[HttpPost(""), ProducesResponseType(201, Type = typeof(ResultResponseMessage<NewFooMessageResponse>))]
public async Task<IActionResult> NewFoo([FromBody] NewFooMessageRequest request)
{
var result = new ResultResponseMessage<NewFooMessageResponse>(request);
var response = new NewFooMessageResponse
{
CreatedAt = DateTime.Now.ToUniversalTime(),
FooId = new Random().Next(100),
FooMessage = new FooMessage
{
Description = request.FooMessage.Description,
Name = request.FooMessage.Name
}
};
result.SetReturn(response);
result.CreateResponseCreated();
return await Task.FromResult(result);
}
[HttpGet("{id}"), ProducesResponseType(200, Type = typeof(ResultResponseMessage<FooMessageResponse>))]
public async Task<IActionResult> GetFoo(GetFooMessageRequest request)
{
var result = new ResultResponseMessage<FooMessageResponse>(request);
var response = new FooMessageResponse
{
FooMessage = new FooMessage
{
Description = "Specialist .NET",
Name = "Jhon Silva"
}
};
result.SetReturn(response);
return await Task.FromResult(result);
}
[HttpPut("{id}"), ProducesResponseType(200, Type = typeof(ResultResponseMessage<UpdateFooMessageResponse>))]
public async Task<IActionResult> UpdateFoo(UpdateFooMessageRequest request)
{
var result = new ResultResponseMessage<UpdateFooMessageResponse>(request);
var response = new UpdateFooMessageResponse
{
UpdatedAt = DateTime.Now.ToUniversalTime(),
FooId = request.FooId,
FooMessage = new FooMessage
{
Description = request.FooMessage.Description,
Name = request.FooMessage.Name
}
};
result.SetReturn(response);
return await Task.FromResult(result);
}
[HttpDelete("{id}"), ProducesResponseType(200, Type = typeof(ResultResponseMessage))]
public async Task<IActionResult> DeleteFoo(DeleteFooMessageRequest request) => await Task.FromResult(new ResultResponseMessage(request));
}
Starting Client creation, you must create an interface.
This interface will be used at the time of dependency injection.
IFooServiceClient with methods to HTTP calls on Foo Microservice.
public interface IFooServiceClient
{
Task<ResultResponseMessage<NewFooMessageResponse>> NewFoo(NewFooMessageRequest request);
Task<ResultResponseMessage<FooMessageResponse>> GetFoo(GetFooMessageRequest request);
Task<ResultResponseMessage<UpdateFooMessageResponse>> UpdateFoo(UpdateFooMessageRequest request);
Task<ResultResponseMessage> DeleteFoo(DeleteFooMessageRequest request);
}
Creating client options is critical as it will be used for dependency injection and must contain the information for the rest call.
Create a FooServiceClientOptions applying the Options design pattern.
public class FooServiceClientOptions
{
public string Name { get; set; }
public string AuthorizationToken { get; set; }
public string BaseAddress { get; set; }
}
To finalize the client sample, create the concrete class that implements the IFooServiceClient methods.
When creating FooServiceClient, see the implementation corresponding to each verb throughout the documentation.
public class FooServiceClient : IFooServiceClient
{
private static string NewFooUri => "api/foo";
private static string GetFooUri => "api/foo/{id}";
private static string UpdateFooUri => "api/foo/{id}";
private static string DeleteFooUri => "api/foo/{id}";
private IHttpRestServiceClient HttpRestServiceClient { get; }
private IOptionsSnapshot<FooServiceClientOptions> Options { get; }
private string ApplicationName { get; }
public FooServiceClient(IOptionsSnapshot<FooServiceClientOptions> options, IHttpRestServiceClient httpRestServiceClient, IConfiguration configuration)
{
if (string.IsNullOrWhiteSpace(options.Value?.AuthorizationToken))
throw new ArgumentNullException("FooServiceClientOptions.AuthorizationToken", "The token of authorization cannot be null.");
if (string.IsNullOrWhiteSpace(options.Value?.BaseAddress))
throw new ArgumentNullException("FooServiceClientOptions.BaseAddress", "The base address cannot be null.");
if (string.IsNullOrWhiteSpace(options.Value?.Name))
throw new ArgumentNullException("FooServiceClientOptions.Name", "The name of client cannot be null.");
ApplicationName = configuration.GetSection("Host:ApplicationName")?.Value;
HttpRestServiceClient = httpRestServiceClient;
Options = options;
}
public async Task<ResultResponseMessage<NewFooMessageResponse>> NewFoo(NewFooMessageRequest request)
{
//See the implementarion on method PostAsync.
}
public async Task<ResultResponseMessage<FooMessageResponse>> GetFoo(GetFooMessageRequest request)
{
//See the implementarion on method GetAsync.
}
public async Task<ResultResponseMessage<UpdateFooMessageResponse>> UpdateFoo(UpdateFooMessageRequest request)
{
//See the implementarion on method PutAsync.
}
public async Task<ResultResponseMessage> DeleteFoo(DeleteFooMessageRequest request)
{
//See the implementarion on method DeleteAsync.
}
}
Properties
BaseAddress
URL that identify host of the HTTP Rest API call.
Declaration
public string BaseAddress { get; }
Property Value
Type | Description |
---|---|
System.String |
MediaTypeAccept
Types of media accepted in the request.
Declaration
public string[] MediaTypeAccept { get; }
Property Value
Type | Description |
---|---|
System.String[] | ["application/json", "application/x-www-form-urlencoded"] |
Name
The logical name of the client to create.
Declaration
public string Name { get; }
Property Value
Type | Description |
---|---|
System.String | MyConnector, MyClient, ... |
Methods
DeleteAsync<TRequestMessage>(String, String, TRequestMessage, Int32, String[])
Asynchronous call to the verb Delete and without response on the return.
Declaration
public Task<ResultResponseMessage> DeleteAsync<TRequestMessage>(string clientName, string uri, TRequestMessage requestMessage, int timeoutInSeconds = 180, params string[] mediaTypeAccept)
where TRequestMessage : RequestMessage, new()
Parameters
Type | Name | Description |
---|---|---|
System.String | clientName | The logical name of the client to create. |
System.String | uri | Path that composes the URL by creating the endpoint that is used in the HTTP Rest call. |
TRequestMessage | requestMessage | Object that represent the request. |
System.Int32 | timeoutInSeconds | Value that represent in seconds the timeout. |
System.String[] | mediaTypeAccept | Types of media accepted in the request. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<ResultResponseMessage> | Object with the default and consolidated result of the request. |
Type Parameters
Name | Description |
---|---|
TRequestMessage | The type of the request to be used in the call. |
Examples
The sample FooServiceClient class is in the contructor example.
//continuing from FooServiceClient
request.AddHeader(Headers.AuthorizationToken, Options.Value.AuthorizationToken);
if (!string.IsNullOrWhiteSpace(ApplicationName))
request.AddHeader(Headers.OriginApplication, ApplicationName);
return await HttpRestServiceClient.DeleteAsync(Options.Value.Name, NewFooUri, request);
The result after execute this method is...
{
"message": "Success.",
"validations": null,
"traceKey": "a6791bca2a514f58bf65a0a303180482"
}
DeleteAsync<TRequestMessage, TResponseMessage>(String, String, TRequestMessage, Int32, String[])
Asynchronous call to the verb Delete and response on the return.
Declaration
public Task<ResultResponseMessage<TResponseMessage>> DeleteAsync<TRequestMessage, TResponseMessage>(string clientName, string uri, TRequestMessage requestMessage, int timeoutInSeconds = 180, params string[] mediaTypeAccept)
where TRequestMessage : RequestMessage, new()
where TResponseMessage : ResponseMessage, new()
Parameters
Type | Name | Description |
---|---|---|
System.String | clientName | The logical name of the client to create. |
System.String | uri | Path that composes the URL by creating the endpoint that is used in the HTTP Rest call. |
TRequestMessage | requestMessage | Object that represent the request. |
System.Int32 | timeoutInSeconds | Value that represent in seconds the timeout. |
System.String[] | mediaTypeAccept | Types of media accepted in the request. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<ResultResponseMessage<TResponseMessage>> | Object with the default and consolidated result of the request. |
Type Parameters
Name | Description |
---|---|
TRequestMessage | The type of the request to be used in the call. |
TResponseMessage | The type of the response to be returned in the result. |
GetAsync<TRequestMessage, TResponseMessage>(String, String, TRequestMessage, Int32, String[])
Asynchronous call to the verb Get.
Declaration
public Task<ResultResponseMessage<TResponseMessage>> GetAsync<TRequestMessage, TResponseMessage>(string clientName, string uri, TRequestMessage requestMessage, int timeoutInSeconds = 180, params string[] mediaTypeAccept)
where TRequestMessage : RequestMessage, new()
where TResponseMessage : ResponseMessage, new()
Parameters
Type | Name | Description |
---|---|---|
System.String | clientName | The logical name of the client to create. |
System.String | uri | Path that composes the URL by creating the endpoint that is used in the HTTP Rest call. |
TRequestMessage | requestMessage | Object that represent the request. |
System.Int32 | timeoutInSeconds | Value that represent in seconds the timeout. |
System.String[] | mediaTypeAccept | Types of media accepted in the request. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<ResultResponseMessage<TResponseMessage>> | Object with the default and consolidated result of the request. |
Type Parameters
Name | Description |
---|---|
TRequestMessage | The type of the request to be used in the call. |
TResponseMessage | The type of the response to be returned in the result. |
Examples
The sample FooServiceClient class is in the contructor example.
//continuing from FooServiceClient
request.AddHeader(Headers.AuthorizationToken, Options.Value.AuthorizationToken);
if (!string.IsNullOrWhiteSpace(ApplicationName))
request.AddHeader(Headers.OriginApplication, ApplicationName);
return await HttpRestServiceClient.GetAsync<GetFooMessageRequest, FooMessageResponse>(Options.Value.Name, NewFooUri, request);
The result after execute this method is...
{
"return": {
"foo": {
"name": "Jhon Silva",
"description": "Specialist .NET"
}
},
"message": "Success.",
"validations": null,
"traceKey": "8c0130b6acb442d3a114e7dbd2ee4e8d"
}
PostAsync<TRequestMessage>(String, String, TRequestMessage, Int32, String[])
Asynchronous call to the verb Post and without response on the return.
Declaration
public Task<ResultResponseMessage> PostAsync<TRequestMessage>(string clientName, string uri, TRequestMessage requestMessage, int timeoutInSeconds = 180, params string[] mediaTypeAccept)
where TRequestMessage : RequestMessage, new()
Parameters
Type | Name | Description |
---|---|---|
System.String | clientName | The logical name of the client to create. |
System.String | uri | Path that composes the URL by creating the endpoint that is used in the HTTP Rest call. |
TRequestMessage | requestMessage | Object that represent the request. |
System.Int32 | timeoutInSeconds | Value that represent in seconds the timeout. |
System.String[] | mediaTypeAccept | Types of media accepted in the request. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<ResultResponseMessage> | Object with the default and consolidated result of the request. |
Type Parameters
Name | Description |
---|---|
TRequestMessage | The type of the request to be used in the call. |
PostAsync<TRequestMessage, TResponseMessage>(String, String, TRequestMessage, Int32, String[])
Asynchronous call to the verb Post and response on the return.
Declaration
public Task<ResultResponseMessage<TResponseMessage>> PostAsync<TRequestMessage, TResponseMessage>(string clientName, string uri, TRequestMessage requestMessage, int timeoutInSeconds = 180, params string[] mediaTypeAccept)
where TRequestMessage : RequestMessage, new()
where TResponseMessage : ResponseMessage, new()
Parameters
Type | Name | Description |
---|---|---|
System.String | clientName | The logical name of the client to create. |
System.String | uri | Path that composes the URL by creating the endpoint that is used in the HTTP Rest call. |
TRequestMessage | requestMessage | Object that represent the request. |
System.Int32 | timeoutInSeconds | Value that represent in seconds the timeout. |
System.String[] | mediaTypeAccept | Types of media accepted in the request. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<ResultResponseMessage<TResponseMessage>> | Object with the default and consolidated result of the request. |
Type Parameters
Name | Description |
---|---|
TRequestMessage | The type of the request to be used in the call. |
TResponseMessage | The type of the response to be returned in the result. |
Examples
The sample FooServiceClient class is in the contructor example.
//continuing from FooServiceClient
request.AddHeader(Headers.AuthorizationToken, Options.Value.AuthorizationToken);
if (!string.IsNullOrWhiteSpace(ApplicationName))
request.AddHeader(Headers.OriginApplication, ApplicationName);
return await HttpRestServiceClient.PostAsync<NewFooMessageRequest, NewFooMessageResponse>(Options.Value.Name, NewFooUri, request);
The result after execute this method is...
{
"return": {
"id": 11,
"foo": {
"name": "Stephen Hawking",
"description": "Theoretical physicist"
},
"createdAt": "2019-11-07T18:39:05.551Z"
},
"message": "Created successfully.",
"validations": null,
"traceKey": "eb9eec87da4a49c7b2cf906322ff1539"
}
PostGzipAsync<TRequestMessage>(String, String, TRequestMessage, Int32, String[])
Asynchronous call to the Post verb with the request compressed via gzip and without response on the return.
Declaration
public Task<ResultResponseMessage> PostGzipAsync<TRequestMessage>(string clientName, string uri, TRequestMessage requestMessage, int timeoutInSeconds = 180, params string[] mediaTypeAccept)
where TRequestMessage : RequestMessage, new()
Parameters
Type | Name | Description |
---|---|---|
System.String | clientName | The logical name of the client to create. |
System.String | uri | Path that composes the URL by creating the endpoint that is used in the HTTP Rest call. |
TRequestMessage | requestMessage | Object that represent the request. |
System.Int32 | timeoutInSeconds | Value that represent in seconds the timeout. |
System.String[] | mediaTypeAccept | Types of media accepted in the request. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<ResultResponseMessage> | Object with the default and consolidated result of the request. |
Type Parameters
Name | Description |
---|---|
TRequestMessage | The type of the request to be used in the call. |
PostGzipAsync<TRequestMessage, TResponseMessage>(String, String, TRequestMessage, Int32, String[])
Asynchronous call to the Post verb with the request compressed via gzip and response on return.
Declaration
public Task<ResultResponseMessage<TResponseMessage>> PostGzipAsync<TRequestMessage, TResponseMessage>(string clientName, string uri, TRequestMessage requestMessage, int timeoutInSeconds = 180, params string[] mediaTypeAccept)
where TRequestMessage : RequestMessage, new()
where TResponseMessage : ResponseMessage, new()
Parameters
Type | Name | Description |
---|---|---|
System.String | clientName | The logical name of the client to create. |
System.String | uri | Path that composes the URL by creating the endpoint that is used in the HTTP Rest call. |
TRequestMessage | requestMessage | Object that represent the request. |
System.Int32 | timeoutInSeconds | Value that represent in seconds the timeout. |
System.String[] | mediaTypeAccept | Types of media accepted in the request. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<ResultResponseMessage<TResponseMessage>> | Object with the default and consolidated result of the request. |
Type Parameters
Name | Description |
---|---|
TRequestMessage | The type of the request to be used in the call. |
TResponseMessage | The type of the response to be returned in the result. |
PutAsync<TRequestMessage>(String, String, TRequestMessage, Int32, String[])
Asynchronous call to the verb Put and without response on the return.
Declaration
public Task<ResultResponseMessage> PutAsync<TRequestMessage>(string clientName, string uri, TRequestMessage requestMessage, int timeoutInSeconds = 180, params string[] mediaTypeAccept)
where TRequestMessage : RequestMessage, new()
Parameters
Type | Name | Description |
---|---|---|
System.String | clientName | The logical name of the client to create. |
System.String | uri | Path that composes the URL by creating the endpoint that is used in the HTTP Rest call. |
TRequestMessage | requestMessage | Object that represent the request. |
System.Int32 | timeoutInSeconds | Value that represent in seconds the timeout. |
System.String[] | mediaTypeAccept | Types of media accepted in the request. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<ResultResponseMessage> | Object with the default and consolidated result of the request. |
Type Parameters
Name | Description |
---|---|
TRequestMessage | The type of the request to be used in the call. |
PutAsync<TRequestMessage, TResponseMessage>(String, String, TRequestMessage, Int32, String[])
Asynchronous call to the verb Put and response on the return.
Declaration
public Task<ResultResponseMessage<TResponseMessage>> PutAsync<TRequestMessage, TResponseMessage>(string clientName, string uri, TRequestMessage requestMessage, int timeoutInSeconds = 180, params string[] mediaTypeAccept)
where TRequestMessage : RequestMessage, new()
where TResponseMessage : ResponseMessage, new()
Parameters
Type | Name | Description |
---|---|---|
System.String | clientName | The logical name of the client to create. |
System.String | uri | Path that composes the URL by creating the endpoint that is used in the HTTP Rest call. |
TRequestMessage | requestMessage | Object that represent the request. |
System.Int32 | timeoutInSeconds | Value that represent in seconds the timeout. |
System.String[] | mediaTypeAccept | Types of media accepted in the request. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<ResultResponseMessage<TResponseMessage>> | Object with the default and consolidated result of the request. |
Type Parameters
Name | Description |
---|---|
TRequestMessage | The type of the request to be used in the call. |
TResponseMessage | The type of the response to be returned in the result. |
Examples
The sample FooServiceClient class is in the contructor example.
//continuing from FooServiceClient
request.AddHeader(Headers.AuthorizationToken, Options.Value.AuthorizationToken);
if (!string.IsNullOrWhiteSpace(ApplicationName))
request.AddHeader(Headers.OriginApplication, ApplicationName);
return await HttpRestServiceClient.PutAsync<UpdateFooMessageRequest, UpdateFooMessageResponse>(Options.Value.Name, NewFooUri, request);
The result after execute this method is...
{
"return": {
"id": 11,
"foo": {
"name": "Stephen William Hawking",
"description": "English theoretical physicist"
},
"updatedAt": "2019-11-07T18:42:04.866Z"
},
"message": "Success.",
"validations": null,
"traceKey": "c12903bd1ee2437096446d8a3050ceca"
}
PutGzipAsync<TRequestMessage>(String, String, TRequestMessage, Int32, String[])
Asynchronous call to the Put verb with the request compressed via gzip and without response on the return.
Declaration
public Task<ResultResponseMessage> PutGzipAsync<TRequestMessage>(string clientName, string uri, TRequestMessage requestMessage, int timeoutInSeconds = 180, params string[] mediaTypeAccept)
where TRequestMessage : RequestMessage, new()
Parameters
Type | Name | Description |
---|---|---|
System.String | clientName | The logical name of the client to create. |
System.String | uri | Path that composes the URL by creating the endpoint that is used in the HTTP Rest call. |
TRequestMessage | requestMessage | Object that represent the request. |
System.Int32 | timeoutInSeconds | Value that represent in seconds the timeout. |
System.String[] | mediaTypeAccept | Types of media accepted in the request. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<ResultResponseMessage> | Object with the default and consolidated result of the request. |
Type Parameters
Name | Description |
---|---|
TRequestMessage | The type of the request to be used in the call. |
PutGzipAsync<TRequestMessage, TResponseMessage>(String, String, TRequestMessage, Int32, String[])
Asynchronous call to the Put verb with the request compressed via gzip and response on return.
Declaration
public Task<ResultResponseMessage<TResponseMessage>> PutGzipAsync<TRequestMessage, TResponseMessage>(string clientName, string uri, TRequestMessage requestMessage, int timeoutInSeconds = 180, params string[] mediaTypeAccept)
where TRequestMessage : RequestMessage, new()
where TResponseMessage : ResponseMessage, new()
Parameters
Type | Name | Description |
---|---|---|
System.String | clientName | The logical name of the client to create. |
System.String | uri | Path that composes the URL by creating the endpoint that is used in the HTTP Rest call. |
TRequestMessage | requestMessage | Object that represent the request. |
System.Int32 | timeoutInSeconds | Value that represent in seconds the timeout. |
System.String[] | mediaTypeAccept | Types of media accepted in the request. |
Returns
Type | Description |
---|---|
System.Threading.Tasks.Task<ResultResponseMessage<TResponseMessage>> | Object with the default and consolidated result of the request. |
Type Parameters
Name | Description |
---|---|
TRequestMessage | The type of the request to be used in the call. |
TResponseMessage | The type of the response to be returned in the result. |