Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I automatically generate refit interfaces from existing Controllers?

I am investigating the refit library and evaluating if I is worth integrating in my project.

Let's say I have this Controller that accepts a POST message with a specific contract:

[Route("api/[controller]")]
[ApiController]
public class KeepAliveController : ControllerBase
{
    [HttpPost]
    public IActionResult Post(KeepAliveContract keepAliveContract)
    {
        // 
    }
}

From what I understand from the refit documentation, I have to create an interface. Let's call it IKeepAliveService. It would look like this:

public interface IKeepAliveService
{
    [Post("api/keepalive")]
    Task SendKeepAliveAsync(KeepAliveContract keepAliveContract);
}

This way of doing things lead to potential runtime errors, if I mess up the route in the PostAttribute or in the signature itself.

Question

Is there a way to automatically generate this interface out of the existing controllers and, as such reduce the risk of bugs?

like image 511
Kzrystof Avatar asked Oct 17 '18 15:10

Kzrystof


1 Answers

You can certainly do this either by using C# 9 Source Generators or Fody IL Weaving.

but another solution is to use a live Roslyn analyzer with a code fix on top of the Refit library and let it handle the generation of type safe clients. because instead of reinventing the wheel, why not just save time and effort and build on top of something that already exists, documented, stable and maintained like Refit rather then rolling your own implementation.

in order for the analyzer to work you have to enable routing by action name in your web api config, and also each controller has to implement its corresponding Refit interface.

// routing by action name
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

what the analyzer will do is check if the route string specified in the route attribute match the method signature. if invalid routes are detected, the compiler will report compilation errors and will also provide a fix.

this way you will never have mistakes in your route string, and even if you did the compiler will notify you.

here is the code for a simple Refit route analyzer that I made, which will give you a good idea of how it works.

PS: The first rule of programming is Don't Reinvent The Wheels.

like image 134
Joseph Avatar answered Sep 18 '22 07:09

Joseph