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. «Забывчивые» методы не проверяют статус ответа совсем.