In the sqlonfhir server (and I believe the Spark server also) the processing of the parameters is not done through webapi routing.
We both use the routing to extract the resourcename, id, operation (and history and versionId) all other functionality is done manually by extracting the content from the RequestUrl and processing it.
[HttpGet, Route("{ResourceName}/{id}/_history/{vid}")]
public HttpResponseMessage Get(string ResourceName, string id, string vid)
{
var buri = this.CalculateBaseURI("{ResourceName}");
fhirstore.RegisterKnownUrl(buri);
if (!Id.IsValidValue(id))
{
throw new FhirServerException(HttpStatusCode.BadRequest, "ID [" + id + "] is not a valid FHIR Resource ID");
}
IModelBase model = GetModel(ResourceName, GetInputs(buri));
var resource = model.Get(id, vid, summary);
if (resource != null)
{
var msg = Request.ResourceResponse(resource, HttpStatusCode.OK);
msg.Headers.Location = resource.ResourceIdentity().WithBase(resource.ResourceBase);
msg.Headers.Add("ETag", String.Format("\"{0}\"", resource.Meta.VersionId));
return msg;
}
// this request is a "you wanted what?"
return Request.CreateResponse(HttpStatusCode.NotFound);
}
(Not a complete code extract - I've stripped the code that handles binary resources, and the _summary parameter content processing)
Another Item from this code that is worth noting, that processing is done within the model (so I can unit test external to the web context).
And the CalculateBaseURI method ensures that the URL on the request is applied to the location on the result, without needing to have a configuration setting that tells the server what to put there.
And while i'm discussing it, we use media formatters to parse the resources content too.