-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Generating REST Clients for .NET Minimal / Web API APIs. #36636
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@bradygaster is interested in this as well |
@davidfowl I just assigned it to him. We had a conversation on this. |
Just putting down some thoughts that came to mind today. Would't it be possible to use a Source generator for this case? Using Attributes in a way of something like this: //Example partially taken from reactiveui/refit
public interface IGithubApi
{
[Get("/users")]
[Response(ResponseType.Xml)] //Using XmlDeserializer on this endpoint
public IAsyncEnumerable<User> GetUserAsync();
[Get("/users")]
[Response(ResponseType.Json)] //Using JsonDeserializer
public IAsyncEnumerable<User> GetUsersAsync(CancellationToken cancellationToken);
[Get("/users/{user}")]
public Task<User> GetUserAsync(string user, CancellationToken cancellationToken);
[Get("/users/{user}")]
public Stream GetUserStreamAsync(string user, CancellationToken cancellationToken);
}
[Apiclient<IGithubApi>] //[ApiClient(typeof(IGithubClient))]
public partial class GithubApi
{
} which would result in something like this: public partial class GithubApi : IGithubApi
{
private readonly HttpClient _client;
public GithubApi(HttpClient client)
{
_client = client;
}
public async IAsyncEnumerable<User> GetUsersAsync()
{
using var responseMessage = await _client.GetAsync("/users");
if (!responseMessage.IsSuccessStatusCode)
{
//something doing here?
}
await using var stream = await responseMessage.Content.ReadAsStreamAsync();
var reader = XmlReader.Create(stream);
var serializer = new XmlSerializer(typeof(User[]));
if (!serializer.CanDeserialize(reader))
{
throw new InvalidOperationException("Not Deserializable");
}
var entries = (User[])serializer.Deserialize(reader);
if (entries == null) yield break;
foreach (var entry in entries)
{
yield return entry;
}
}
public async IAsyncEnumerable<User> GetUsersAsync([EnumeratorCancellation]CancellationToken cancellationToken)
{
using var responseMessage = await _client.GetAsync("/users", cancellationToken);
if (!responseMessage.IsSuccessStatusCode)
{
//something doing here?
}
await using var stream = await responseMessage.Content.ReadAsStreamAsync(cancellationToken);
var entries = JsonSerializer.DeserializeAsyncEnumerable<User>(stream, JsonSerializerOptions.Default, cancellationToken);
await foreach (var entry in entries.WithCancellation(cancellationToken))
{
yield return entry;
}
}
public Task<User> GetUserAsync(string user, CancellationToken cancellationToken)
{
}
public async Task<Stream> GetUserStreamAsync(string user, CancellationToken cancellationToken)
{
using var responseMessage = await _client.GetAsync($"/users/{user}", cancellationToken);
if (!responseMessage.IsSuccessStatusCode)
{
//something doing here?
}
return await responseMessage.Content.ReadAsStreamAsync(cancellationToken);
}
public async Task<string> GetUserStringAsync(string user, CancellationToken cancellationToken)
{
using var responseMessage = await _client.GetAsync($"/users/{user}", cancellationToken);
if (!responseMessage.IsSuccessStatusCode)
{
//something doing here?
}
return stream = await responseMessage.Content.ReadAsStringAsync(cancellationToken);
}
} It's just something to show what I had in mind and maybe it's something worth thinking about? I was also thinking of a way to proccess different StatusCodes, and thought of the TypedResults.NotFound, Ok etc.... |
I love the idea of a source generator that outputs Refit clients. I spoke with @clairernovotny about this a few times. My goal would be to have a Refit provider for the REST API client generation feature in VS Connected Services. So, cc @vijayrkn, with whom I've discussed this idea a few times and seemed receptive to it. |
Is your feature request related to a problem? Please describe.
Investigate how retrofit or refit can be used for REST Client generations with dotnet-api tooling.
Describe the solution you'd like
Retrofit or refit are great libraries for generating REST clients for mostly android apps. They allow you to define an interface containing a set of endpoints that your application will be interacting with, and then you can generate the implementation code. We would like to investigate the possibility of using retrofit/refit/or something new for generating REST Client implementations with dotnet-api tooling.
Additional context
The text was updated successfully, but these errors were encountered: