Skip to content

Using the DynamicRestClient

Don Kackman edited this page Jun 22, 2014 · 6 revisions

The portable version of this code has both a client class and a proxy class that use System.Net.Http.HttpClient for communication.

The DynamicRestClient encapsulates the HttpClient instance and makes some assumptions about how to configure it to support the most common ways Rest APIs are constructed. An HttpClient is created for each verb invocation. Calling code does not need to worry about lifetime management or disposal.

dynamic client = new DynamicRestClient("http://dev.virtualearth.net/REST/v1/");

var result = await client.Locations.get(postalCode: "55116", countryRegion: "US", key: CredentialStore.Key("bing"));

Assert.AreEqual(result.statusCode, 200);
Assert.IsTrue(result.resourceSets.Count > 0);
Assert.IsTrue(result.resourceSets[0].resources.Count > 0);

var r = result.resourceSets[0].resources[0].point.coordinates;
Assert.IsTrue((44.9108238220215).AboutEqual((double)r[0]));
Assert.IsTrue((-93.1702041625977).AboutEqual((double)r[1]));

The DynamicRestClient constructor has an optional parameter where calling code can supply default parameters and headers.

var defaults = new DynamicRestClientDefaults();
defaults.DefaultParameters.Add("key", CredentialStore.Key("bing"));

dynamic client = new DynamicRestClient("http://dev.virtualearth.net/REST/v1/", defaults);

var result = await client.Locations.get(postalCode: "55116", countryRegion: "US");

These defaults apply to any request made on any endpoint created from the root client object.

Conventions

Unnamed Arguments

When invoking the http verb methods, unnamed arguments are added to the request body as content. The type of the argument is used to determine how to serialize the argument into the request body.

  • Arguments that of types Stream or StreamInfo are serialized as StreamContent
  • Any argument of type byte[] will be serialized as a ByteArrayContent
  • Any argument of type HttpContent is passed directly to the request without modification (see below)
  • All other types are serialized as json

Multipart Content

Passing multiple unnamed arguments will result in multi-part content. Objects are serialized per the rules above in the order they are passed.

Named Arguments

Named arguments are passed following the C# named arguments syntax. Named arguments are considered to be request parameters with the name being the parameter name and its value the parameter value.

dynamic client = new DynamicRestClient("http://openstates.org/api/v1/")
var result = await client.bills.get(state: "mn", chamber: "upper", status: "passed_upper");

Would result in the following endpoint url: http://openstates.org/api/v1/bills?state=mn&chamber=upper&status=passed_upper

By default POST request parameters are serialized to the request body as application/x-www-form-urlencoded. If a POST request parameter needs to be a url query parameter, wrap the value object in a PostUrlParam, which will force it to be part of the endpoint url.

var defaults = new DynamicRestClientDefaults();
defaults.OAuthToken = _token;

dynamic google = new DynamicRestClient("https://www.googleapis.com/", defaults);

using (var stream = new StreamInfo(File.OpenRead(@"D:\temp\test.png"), "image/png"))
{
    dynamic result = await google.upload.storage.v1.b.unit_tests.o.post(stream, name: new PostUrlParam("test_object"), uploadType: new PostUrlParam("media"));
    Assert.IsNotNull(result);
}

For all other request types named arguemnts result in query parameters.

Escape Mechanisms

Because the DynamicRestClient encapsulates the HttpClient there are a couple of escape mechanisms to allow finer grained control over requests than might be implemented by convention.

The first is that the DynamicRestClient constructor can also take an optional callback method so calling code can perform any final configuration of an HttpRequest immediately before its invocation. If supplied this callback will by called before each invocation of an http request. This allows the caller to set an additional request headers.

dynamic proxy = new DynamicRestClient("https://www.googleapis.com/oauth2/v1/userinfo", null, async request =>
    {
        var token = await _oauth2Service.GetAccessToken();
        request.Headers.Authorization = new AuthenticationHeaderValue("OAuth", token);
    });

The second is that an HttpContent object can be passed directly as an unnamed argument. This allows the caller to configure any content headers. The HttpContent object will be passed directly to the request as is.

Clone this wiki locally