locked
HOWTO Injecting params to all calls to RESTful Api? RRS feed

  • Question

  • User100248066 posted

    There are both ASP.Net Core & ASP.Net MVC5 sites that are calling restful services which all require two tokens for audit purposes:  token1, token2.  Here is an example of the 

    public interface ItemApi 
    {
        GetItemResponse GetItem (int itemId, int token1, string token2);
    }

    The developer making the call should not be concerned with the values of token1/token2.  While it is possible for the developer to always set them, the goal is to find a way to have the infrastructure set the values for the developer.  

    One idea is to introduce an interceptor to set the values before the actual call is made.  After reading through all the documentation on Castle Windsor's Dynamic Proxy and Dora, it appears that the method the interceptor is working on must be annotated.  Annotation is not an option because the interface is autogenerated from the OpenAPI Tool. Is there a way to use interceptors without annotations?

    Is there any other way to insert params into each call to given RESTful services?

    Wednesday, February 10, 2021 4:24 PM

All replies

  • User475983607 posted

    I assume the tokens are persisted somewhere in the client.  Why can't you simply create a HttpClient factory or simple utility that grabs the tokens from the persistent store?

    Wednesday, February 10, 2021 4:35 PM
  • User-474980206 posted

    it not clear how without annotations, an auto generated proxy could determine which parameters are token values. while you could create a signature mapping document, it seems it would be just as hard to produce as hand coding the proxy.

    public class proxy
    {
        private int _token1
        private string _token2
        private ItemApi;
        ...
        
        public GetItemResponse GetItem (int itemId) => ItemApi.GetItem (itemId, _token1, _token2);
        ...
    }
    

     

    Wednesday, February 10, 2021 8:40 PM
  • User100248066 posted

    it not clear how without annotations, an auto-generated proxy could determine which parameters are token values. while you could create a signature mapping document, it seems it would be just as hard to produce as hand-coding the proxy.

    The thought process is to use reflection.  Token1 is ALWAYS named token1 and is ALWAYS an int, Token2 is always token2 and a string.  The interceptor will interrogate the params passed in to find the two values, check to see if they are set, and if they are not set, then set them correctly.

    Reflection is super slow, so there will be two phases of development:

    1. Get it working in general
    2. figure out how to cache the reflection data to improve preformance. 
    Thursday, February 11, 2021 7:22 PM
  • User-474980206 posted

    Compared to a web service call reflection is not slow. If you use binding, it’s using reflection. You can get a small boost by caching memberinfo. 

    the real issue is your dynamic proxy methods will not be strongly typed. Seems like using the solution is more painful than the problem. If you inherited from a rest generatied api, you could prprovide additional properties  for the token values.

    a more common solution to this problem is to pass the tokens as headers, so the api is not changed.

    Thursday, February 11, 2021 8:41 PM
  • User-1982062310 posted

    One idea is to introduce an interceptor to set the values before the actual call is made.  After reading through all the documentation on Castle Windsor's Dynamic Proxy and Dora, it appears that the method the interceptor is working on must be annotated.  Annotation is not an option because the interface is autogenerated from the OpenAPI Tool. Is there a way to use interceptors without annotations?

    Another way would be to wrap the autogenerated interfaces with your own proxy classes that obtain the token values in centralised to your app manner and expose endpoints that are devoid of token params to the rest of your app.

    Not only this removes the reflection issue, it makes writing unit tests slightly easier.

    Thursday, February 11, 2021 9:27 PM
  • User100248066 posted

    a more common solution to this problem is to pass the tokens as headers, so the api is not changed.

    It is funny that you mention putting the info into headers.  I was browsing around some other topics and saw a reference to info being in headers and I realized that IS the solution!  You simply confirmed that idea!!!!!  Thanks for being that second voice of wisdom!

    Thursday, February 11, 2021 9:39 PM
  • User100248066 posted

    a more common solution to this problem is to pass the tokens as headers, so the api is not changed.

    so I have modified the RESTful service to state the tokens are in the header and when I test via Swagger, all is GREAT!  Now the question is:  How do I do this on the client?  I need to support both ASP.Net Core AND ASP.Net MVC 5.

    I am thinking in ASP.Net Core the solution might be to implement an IHttpClientFactory and inject the values there, but my first client happens to be ASP.Net MVC 5 using Unity.  So any thoughts, tips, or best yet URL's to examples would be very welcome!

    Friday, February 12, 2021 4:18 PM
  • User475983607 posted

    The code is pretty simple and the concept is openly covered in the official docs.  Can you show us what you have tried so we can understand why you are having problems?

    https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-5.0#typed-clients

    Friday, February 12, 2021 5:05 PM
  • User100248066 posted

    Well, considering how well document the ASP.Net Core code is, I am sure it is easy, but my first client is not ASP.Net Core, but ASP.Net MVC 5!

    Friday, February 12, 2021 7:44 PM
  • User475983607 posted

    Well, considering how well document the ASP.Net Core code is, I am sure it is easy, but my first client is not ASP.Net Core, but ASP.Net MVC 5!

    If you take a closer look at the pattern, the code takes advantage of the constructor to set header fields.  I agree ASP.NET Core is a bit more convenient using the dependencies injection framework but constructors work the same in ASP.NET as they do in ASP.NET Core.  The ASP.NET developer with simply "new' the class.  

    The bit that is missing from your requirement is where and when the tokens are persisted.  You'll need to write code to get the tokens.  

    Friday, February 12, 2021 8:26 PM