Service Client Version

I have a 3rd party api that uses a version string as part of the uri in the format v[0-9*].0.

Currently the serviceclient has an int Version property from IHasVersion and that interface can also be used on each dto to populate the value from the client which would be ideal.

I can’t use an interpolated/partial token in the route e.g.

public class Dto : IHasVersion {
  public int Version {get;set;}

So just wondering if I’m missing something or if there is a neat way of populating or inject the version string on each request?

I’m using a custom ServiceClient inherited from JsonServiceClient if that helps any…

Also, what would be best way to enforce all dto’s inherit from a specific interface for this custom client to enforce behaviours like the version route injection?

The Variable needs to match the entire path component, e.g:

public class MyRequest
  public string Version { get; set; }

You can use a custom route rule to limit the route matching with custom C# code but that’s only for route matching in ServiceStack Services.

If you’re trying to use Request DTOs for an external 3rd Party API you can customize the URL that’s used with the IUrlFilter, e.g:

public class Dto : IHasVersion, IUrlFilter 
    public int Version { get; set; }

    public string ToUrl(string absoluteUrl) => 
        absoluteUrl.Replace($"/someapi/{Version}/", $"/someapi/v{Version}.0/");

Which should do what you’re after where the Service Client will populate the Version number on all Request DTOs which will use your desired URL format:

 new Dto { Version = 2 }.ToGetUrl() //= /someapi/v2.0/someendpoint

The StripeGateway has more examples for generating custom Requests for 3rd APIs.


I ended up overriding the ResolveTypedUrl method on the serviceclient adding an additional static extension method to check and populate my own interface IHasVersionString.ApiVersion string property. I can then use this as the token on the route attribute.

Also added check on SendRequest override to enforce sending only dto’s with this interface to the external api.

Seems to work fine and it means I don’t have to set custom ToUrl on each one.

1 Like