Skip to content

Responses

Stanislav Molchanovskiy edited this page Nov 30, 2021 · 3 revisions

You can get the full HTTP response from the client's method, not just the body. If your interface is used only as a client and you want to always get an HTTP response, you have the following options: return the NClient IHttpResponse or return the original transport response.

HTTP response

If you use a default transport (NClient.Providers.Transport.Http.System) and want to receive an HTTP response along with a deserialized body, return IHttpResponse or IHttpResponse<T>:

public interface IMyClient
{
    [GetMethod] Task<IHttpResponse<Entity>> GetAsync(int id);
    [PostMethod] Task<IHttpResponse> PostAsync(Entity entity);
}
...

HttpResponse<Entity> response = await myClient.GetAsync(id: 1);
Entity entity = response.EnsureSuccess().Value;

If you want to specify the type of expected error that is returned in body with failed HTTP statuses, then use IHttpResponseWithError<TValue, TError> or IHttpResponseWithError<TError>:

public interface IMyClient
{
    [GetMethod] Task<IHttpResponseWithError<Entity, Error>> GetAsync(int id);
    [PostMethod] Task<IHttpResponseWithError<Error>> PostAsync(Entity entity);
}
...

IHttpResponseWithError<Entity, Error> response = await myClient.GetAsync(id: 1);
Error? error = response.Error;

Oviously controller cannot implemetn the interface that returns HTTP response, so the controller should return what it should, and you need to create a client interface, inherit it from the controller interface and override the method by changing the return type to HTTP response (see OverrideAttribute in Annotation section).

Transport response

There are cases when there is not enough functionality of IHttpResponse, then you can return transport responses. If you use NClient.Providers.Transport.Http.System transport package, you can do this:

public interface IMyClient
{
    [GetMethod] Task<HttpResponseMessage> GetAsync(int id);
}

or if you use NClient.Providers.Transport.Http.RestSharp transport package:

public interface IMyClient
{
    [GetMethod] Task<IRestResponse> GetAsync(int id);
}

Unlike the first option with IHttpResponse return, you can get a transport response without overriding and additional methods in the client. To do this, the client interface must inherit the INClient interface, then you will be able to do this:

public interface IMyClient : INClient
{
    [GetMethod] Task<Entity> GetAsync(int id);
}
...
IHttpResponse<Entity> response = await myClient.AsTransport().GetTransportResponse(x => x.GetAsync(id: 1));

In general, this way is not recommended because it complicates unit testing, but sometimes it can be useful.