UrlQueryBuilder

Date: 2019-10-15
using System.Web;

public class HttpHelper
{
	public static string UrlDecode(string input) => HttpUtility.UrlDecode(input);
	public static string UrlEncode(string input) => HttpUtility.UrlEncode(input);
}
public class UrlQueryBuilder
{
	private IDictionary<string, string> qry = new Dictionary<string, string>();
	public UrlQueryBuilder Set(string key, object value)
	{
		if (value is DateTime)
			value = ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
		qry[key] = value.ToString();
		return this;
	}
	public string Build()
	{
		if (!qry.Any()) return string.Empty;
		return string.Join("&", qry.Select(x => string.Join("=", x.Key, HttpHelper.UrlEncode(x.Value))));
	}
}

private RestApiClient GetRestApiClient(string apiKey)
{
	string userName = apiKey;
	string password = "";
	string webserviceApiUrl = "https://test.com/api/";
	RestApiClient client = new RestApiClient(webserviceApiUrl, new NetworkCredential(userName, password));
	return client;
}

private async Task CheckRateLimit(HttpResponseMessage response)
{
	if (response.Headers.Contains("X-RateLimit-Remaining"))
	{
		var rateLimit = int.Parse(response.Headers.GetValues("X-RateLimit-Limit").FirstOrDefault());
		var rateLimitRemaining = int.Parse(response.Headers.GetValues("X-RateLimit-Remaining").FirstOrDefault());
		if (rateLimitRemaining < 10)
			await Task.Delay(5000); // wait some time to prevent hitting the limit
	}
}

private async Task<T> GetSingle<T>(string apiKey, string path)
{
	using (var client = GetRestApiClient(apiKey))
	{
		var response = await client.Get<T>($"{path}");
		await CheckRateLimit(response.Response);
		return response.Result;
	}
}

private async Task<IEnumerable<T>> GetPaged<T>(string apiKey, string path, QueryBuilder query = null)
{
	if (query == null)
		query = new QueryBuilder();
	using (var client = GetRestApiClient(apiKey))
	{
		var allItems = new List<T>();
		var page = 0;
		var pageSize = 100;
		var hasMore = true;
		while (hasMore)
		{
			var offset = page * pageSize;
			if (offset > 0)
				query.Set("offset", offset);
			var response = await client.Get<IList<T>>($"{path}?{query.Build()}");
			await CheckRateLimit(response.Response);
			hasMore = response.Result.Count == pageSize;
			allItems.AddRange(response.Result);
			page++;
		}
		return allItems;
	}
}

26720cookie-checkUrlQueryBuilder