Binateq.JsonRestClient
25-04-2018
Разработал и опубликовал пакет для отправки REST-запросов. Сделал его, когда в четвёртый или пятый раз писал однотипное расширение класса HttpClient
.
Проблема
При разработке REST-клиента нужно отсылать на сервере запросы. Выглядят они приблизительно так:
POST http://api.domain.tld/v1/resources
GET http://api.domain.tld/v1/resources?from=2018-04-17T11:37:00&ends_with=bar
PUT http://api.domain.tld/v1/resources/2
В теле запроса могут присутствовать дополнительные параметры, которые чаще всего закодированы в формате JSON. Иногда запросы возвращают результаты, также в формате JSON.
Уровень класса HttpClient
чуть ниже требуемых задач, поэтому его приходится обвязывать расширениями.
Решение
Разработан класс JsonRestClient
с методами отправки REST-запросов и поддержкой JSON.
class Resource
{
public int Id { get; set;}
public string Name { get; set; }
}
var httpClient = new HttpClient();
var baseUri = new Uri("https://api.domain.tld/v1");
var jsonRestClient = new JsonRestClient(httpClient, baseUri);
var resourceId = 100;
resource = await jsonRestClient.GetAsync<Resource>($"resources/{resourceId}");
await jsonRestClient.PostAsync($"resources", new Resource { Name = "foo" });
Для работы объекту JsonRestClient
нужен HttpClient
, чтобы отправлять запросы; и базовый Uri
, чтобы не дублировать часть URI, общую для всех методов.
Параметры строки запроса
Параметры запроса можно передавать либо в пути (до знака вопроса ?
), либо в строке запроса (после знака вопроса ?
):
GET http://api.domain.tld/v1/resources/314/subresources?from=2018-04-17T11:37:00&ends-with=bar
В примере 314
— это параметр, переданный в пути /v1/resources/314/subresources
, а 2018-04-17T11:37:00
и bar
— параметры, переданные в строке запроса. В отличие от 314
, каждый из них имеет имя, в нашем примере from
и ends-with
.
Вот так мы можем отправить запрос из примера:
var resourceId = 314;
var from = new DateTime(2018, 04, 17, 11, 37, 00);
var endsWith = "bar";
var resource = await jsonRestClient.GetAsync<Resource>($"resources/{resourceId}"
new Dictionary<object, string>
{
{ nameof(from), from },
{ "ends-with" }, endsWith,
}
);
Статус 404
Для методов Get
в JsonRestClient
предусмотрена форма GetOrDefaultAsync
. Если запрос возвращает статус 404, метод GetOrDefaultAsync
возвратит значение по умолчанию для заданного типа.
С глаз долой — из сердца вон
Для методов Put
и Post
в JsonRestClient
предусмотрена форма PutAndForgetAsync
. Обычные методы Put
/Post
выбрасывают исключение, если статус ответа отличается от 2xx. «Забывчивые» методы не проверяют статус ответа совсем.