patterncsharpMinor
JSON REST client proxy generator
Viewed 0 times
restproxygeneratorclientjson
Problem
Trying to create something really lightweight. Sources are on GitHub.
To create a proxy we need to define an interface first, e.g.:
At this moment we actually know enough to generate a proxy:
We can inject
We can also emit the proxy class for dependency injection:
About error handling – this exception is thrown for unsuccessful HTTP status codes:
We could specify extra type parameter for the
to have generic exception be thrown instead:
So error re
To create a proxy we need to define an interface first, e.g.:
// Fake Online REST API for Testing and Prototyping
[Site("https://jsonplaceholder.typicode.com")]
public interface ITypicode
{
[Get("posts")]
Task GetAsync();
[Get("posts/{0}")]
Task GetAsync(int id);
[Post("posts")]
Task PostAsync([Body] BlogPost data);
[Put("posts/{0}")]
Task PutAsync(int id, [Body] BlogPost data);
[Delete("posts/{0}")]
Task DeleteAsync(int id);
}
public class BlogPost
{
public int UserId { get; set; }
public int Id { get; set; }
public string Title { get; set; }
public string Body { get; set; }
}At this moment we actually know enough to generate a proxy:
ITypicode typicode = RestClient.Create();
BlogPost blogPost = await typicode.PutAsync(1, new BlogPost { Body = "Wow!" });
Console.WriteLine(blogPost.Body);We can inject
HttpMessageHandler:ITypicode typicode = RestClient.Create(handler);We can also emit the proxy class for dependency injection:
Type typicodeType = RestClient.Emit();About error handling – this exception is thrown for unsuccessful HTTP status codes:
public class RestException : Exception
{
public RestException(HttpResponseMessage response)
{
Response = response;
}
public HttpResponseMessage Response { get; }
public override string ToString() =>
Response.Content.ReadAsStringAsync().Result;
}We could specify extra type parameter for the
SiteAttribute:[Site("https://jsonplaceholder.typicode.com", Error = typeof(TypicodeError))]
public interface ITypicode
{
// …
}to have generic exception be thrown instead:
public class RestException : RestException
{
public RestException(HttpResponseMessage response)
: base(response)
{
}
public T Error => JsonConvert.DeserializeObject(ToString());
}So error re
Solution
Usually when I see your questions there isn't much for me to say, because you usually flesh everything out really well. :) (Probably why this has been unanswered so long.)
That said, I think I do have one comment here:
If you have support to edit the
It makes everything more meaningful.
If it's WebAPI you probably don't have access to the source for these attributes, but you can probably wrap them with a new one to add support for this feature. (Adds a little complexity, but should be really awesome to see happen.)
That said, I think I do have one comment here:
If you have support to edit the
HeaderAttribute or the GetAttribute, I would consider replacing the {0}, {1} (etc.) format symbols with a named format symbol.[Get("posts/{id}")]
Task GetAsync(int id);
[Site("https://jsonplaceholder.typicode.com")]
public interface ITypicode
{
[Get("posts/{id}")]
[Header("X-API-KEY: {apiKey}")] // req - in
[Header("Content-Type: {contentType}; charset={charset}")] // res - out
Task GetAsync(
int id, string apiKey, out string contentType, out string charset);
}It makes everything more meaningful.
If it's WebAPI you probably don't have access to the source for these attributes, but you can probably wrap them with a new one to add support for this feature. (Adds a little complexity, but should be really awesome to see happen.)
Code Snippets
[Get("posts/{id}")]
Task<BlogPost> GetAsync(int id);
[Site("https://jsonplaceholder.typicode.com")]
public interface ITypicode
{
[Get("posts/{id}")]
[Header("X-API-KEY: {apiKey}")] // req - in
[Header("Content-Type: {contentType}; charset={charset}")] // res - out
Task<BlogPost> GetAsync(
int id, string apiKey, out string contentType, out string charset);
}Context
StackExchange Code Review Q#140491, answer score: 4
Revisions (0)
No revisions yet.