-
-
Notifications
You must be signed in to change notification settings - Fork 748
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
Composing multiple interfaces for one API. #49
Comments
This isn't possible right now, the best you can do currently is use partial classes (Partial interfaces? Is that a thing?) The idea of nesting objects is kind of interesting though |
Yeah. I'm new to this library, and i'm experimenting with it. Maybe one singe big interface is a better solution, having all the endpoints in one place, it's easier to navigate and understand. I'll play around more. Thanks. |
It seems reasonable for interface-returning properties on API interfaces to return Refit proxies for the returned interface. |
I've begun adding support for it (see here). Currently, a refit interface can be composed of other refit interfaces like this: public interface IServicePart
{
[Get("/")]
Task<List<string>> GetUsers();
[Get("/{user}")]
Task<string> GetUser(string user);
}
public interface IService
{
[Compose("/users")]
IServicePart Users { get; } The attribute is mandatory here, unless we have all the compile time types (requiring another part of Roslyn). What do you think of it ? |
I'm not opposed to it but I'm not sure we need the compose attribute to generate the stubs - as long as all of the interfaces you're composing are in the same project, you should be able to pick up any wrapper interfaces with a second pass:
We could run into problems without an attribute though, because it would mean having to pass the relative paths in when calling @paulcbetts? I think it looks good so far. What else is there still to do on it (other than tests)? I think anything that we're building into the stubs that will throw an exception should raise a warning at build time too, so you'll want to do that as soon as we get #79 merged. |
Am I understanding the semantics right here? public interface IServicePart
{
// Actually makes a request to /users
[Get("/")]
Task<List<string>> GetUsers();
// Actually makes a request to /users/{user}
[Get("/{user}")]
Task<string> GetUser(string user);
}
public interface IService
{
[Compose("/users")]
IServicePart Users { get; }
} How is this better (this is not a rhetorical question, it very may well be!) than: public interface IService
{
IServicePart Users { get; }
}
public class Service
{
IServicePart Users {
get { return RestService.For<IServicePart>("https://myservice.com/users"); }
}
} |
It still allows you to have refit method inside your interface and compose it. This will work: public interface IServicePart
{
// Actually makes a request to /users
[Get("/")]
Task<List<string>> GetUsers();
// Actually makes a request to /users/{user}
[Get("/{user}")]
Task<string> GetUser(string user);
}
public interface IService
{
[Compose("/users")]
IServicePart Users { get; }
[Get("/")]
Task<List<string>> Get();
} Maybe it is too much and interface composition shouldn't be mixed with refit service definition. |
I think it's potentially worse actually - you lose the control over the If we go ahead with it, we will need to make sure we allow for a single |
Sorry, accidentally clicked the button. |
I think you could just do this better with Extension Methods: public interface IService
{
[Get("/")]
Task<List<string>> Get();
}
public static class UsersExtension
{
public static IServicePart Users(this IService This) {
return RestService.For<IServicePart>("https://myservice.com/users");
}
} |
Looks good. Currently, I don't have [Header(...)] inheritance in sub-service, so you have to specify it everywhere. |
Let's close this out then, unless someone comes up with a super cool use-case |
Maybe we could update the Readme to include your solution ? |
@nekresh Can you submit a PR to do that? |
Hi,
Firstly, sorry if this is a obvious question, but is it possible to have one big interface/api defined in multiple pieces?
Maybe a folder structure like this? Where each interface is in its own folder inside a class.
then using just the IAcmeApi interface
I hope it makes sense.
Thank you.
The text was updated successfully, but these errors were encountered: