Search code examples
c#grapevine

Grapevine Rest Server Route Pathinfo with dynamic values


I'm pretty new to C# and need to realise a REST Service so i stumbled over Grapevine. I need to have parts of the URL of the service handed over on service start via config file but I don't manage to hand over the value "clientId" of the config file to the Route's Pathinfo because it's not constant. Here's the part of the code:

[RestResource(BasePath = "/RestService/")]
public class Rest_Resource
{
    public string clientId =  ConfigurationManager.AppSettings["ClientId"];

    [RestRoute(PathInfo = clientId + "/info")]//<-how do I fill Pathinfo with dynamic values?
    public IHttpContext GetVersion(IHttpContext context)
    {....}
    }

I'm using grapevine v4.1.1 as nuget package in visual studio.


Solution

  • While it is possible to change attribute values at runtime, or even use dynamic attributes, an easier solution in this case might be to not use the auto discovery feature exclusively, but use a hybrid approach to route registration.

    Consider the following class that contains two rest routes, but only one of them is decorated with the attribute:

    [RestResource(BasePath = "/RestService/")]
    public class MyRestResources
    {
        public IHttpContext ManuallyRegisterMe(IHttpContext context)
        {
            return context;
        }
    
        [RestRoute(PathInfo = "/autodiscover")]
        public IHttpContext AutoDiscoverMe(IHttpContext context)
        {
            return context;
        }
    }
    

    Since you want to register the first route using a value that is not known until runtime, we can manually register that route:

    // Get the runtime value
    var clientId = "someValue";
    
    // Get the method info
    var mi = typeof(MyRestResources).GetMethod("ManuallyRegisterMe");
    
    // Create the route
    var route = new Route(mi, $"/RestService/{clientId}");
    
    // Register the route
    server.Router.Register(route);
    

    This takes care of manually registering our route that needs a runtime value, but we still want the other routes to be automatically discovered. Since the router will only autodiscover if the routing table is empty when the server starts, we'll have to tell the router when to scan the assemblies. You can do this either before or after you manually register the route:

    server.Router.ScanAssemblies();