Skip to content
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

Make fullstack C# development easier #1605

Open
ysmoradi opened this issue Nov 16, 2023 · 0 comments
Open

Make fullstack C# development easier #1605

ysmoradi opened this issue Nov 16, 2023 · 0 comments

Comments

@ysmoradi
Copy link

As development with blazor and maui growths, there will be more & more projects with C# in their both backend and frontend.
In such a scenario, there could be a shared project that share common code between backend and frontend (for example dto classes).

In refit we use interface with some methods that have attributes such as Get, Post etc.
We could put that interface in a shared project, so api controller can implement it and client can call it to achieve a perfect solution that make api calling somehow strongly typed! Like the old days of WCF services (":
Example:

public interface ICategoryController // in shared project
{
    [Get("/Category/Get")]
    Task<IQueryable<CategoryDto>> Get();

    [Get("/Category/Get/{id}")]
    Task<CategoryDto> Get(int id, CancellationToken cancellationToken = default);

    [Post("/Category/Create")]
    Task<CategoryDto> Create(CategoryDto dto, CancellationToken cancellationToken = default);

    [Put("/Category/Update")]
    Task<CategoryDto> Update(CategoryDto dto, CancellationToken cancellationToken = default);

    [Delete("/Category/Delete/{id}")]
    Task Delete(int id, CancellationToken cancellationToken = default);
}

public partial class CategoryController : ICategoryController // in server
{
    [HttpGet]
    public IQueryable<CategoryDto> Get()
    {
        ...
    }

    [HttpGet("{id:int}")]
    public async Task<CategoryDto> Get(int id, CancellationToken cancellationToken)
    {
        ...
    }

    [HttpPost]
    public async Task<CategoryDto> Create(CategoryDto dto, CancellationToken cancellationToken)
    {
        ...
    }

    [HttpPut]
    public async Task<CategoryDto> Update(CategoryDto dto, CancellationToken cancellationToken)
    {
        ...
    }

    [HttpDelete("{id:int}")]
    public async Task Delete(int id, CancellationToken cancellationToken)
    {
        ...
    }
}

Sadly, this code is not working because the Get method that returns IQueryable has different signature in interface and implementation.
This is just an example and there are more scenarios but luckily, most method signatures are compatible.
I tried to change get method in interface to such a thing:

    [Get("/Category/Get")]
    Task<IQueryable<CategoryDto>> Get() => null;

So I won't have to implement that in api controller at server side and with this approach I can skip a few method signatures that are problematic while enjoying the strongly typed approach for the rest of the method signatures.

But because of this issue and its related PR, so a solution won't work at all.

I can understand that business requirements that @MariusVolkhart has mentioned, but I think we may not skip methods that have refit attributes such as Get and Post at all.

I think the first check could be if the method has refit attributes, then we can check if it has body or not so we can achieve this new design I've mentioned without breaking @MariusVolkhart's requirement.

image

Thanks for your great library ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant