.Net 中具有高级搜索和修饰符的 HL7 FHIR 路由
HL7 FHIR routing with advanced search and modifiers in .Net
我目前正在尝试使用 FHIR 搜索来解决路由问题。
在网页 https://www.hl7.org/fhir/search.html 的 2.1.1.48 字符串段落中,有一节介绍了如何使用修饰符 return 包含或匹配提供的参数值的结果。
例如:
[base]/Patient?name=eve
[base]/Patient?name:contains=eve
[base]/Patient?name:exact=Eve
我从未见过 f.ex 接受带有这些自定义修饰符“?name:exact/contains”的此类 URL。开箱即用的 Web api 服务。
据我所知,在
的行里是不允许写东西的
[Route("{type}/name:contains/{name}")]
public HttpResponseMessage GetContainsName(string name){
//do something
}
[Route("{type}/name:exact/{name}")]
public HttpResponseMessage GetExactName(string name) {
//do something else
}
在sqlonfhir服务器中(我相信Spark服务器也是如此)参数的处理不是通过webapi路由完成的。
我们都使用路由来提取资源名称、ID、操作(以及历史记录和版本 ID),所有其他功能都是通过从 RequestUrl 中提取内容并进行处理来手动完成的。
[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);
}
(不是完整的代码摘录——我已经剥离了处理二进制资源的代码,以及_summary参数内容处理)
此代码中的另一个值得注意的项目是,处理是在模型内完成的(因此我可以在 Web 上下文外部进行单元测试)。
CalculateBaseURI 方法可确保将请求中的 URL 应用于结果中的位置,而无需进行配置设置来告诉服务器要放在那里的内容。
在我讨论它的同时,我们也使用媒体格式化程序来解析资源内容。
这是启动 FHIR 服务器和 运行 的可能解决方案。我使用了 Sparks.Engine 中的一些代码,因此更容易使修饰符以及 "decoding" 和 url.
一起工作
您将有望通过任何一种方法获得成功
这些方法应该接受 url 这样的
fhir/Patient/1
fhir/Patient?name=something
fhir/?_query="nameOfQuery"&name:contains="someName"
服务器本身的代码如下所示
namespace FHIRServer.Controllers
{
[RoutePrefix("fhir"), EnableCors("*", "*", "*", "*")]
[RouteDataValuesOnly]
public class FhirController : ApiController
{
public FhirController()
{
}
[HttpGet, Route("{type}")]
public HttpResponseMessage ResourceQuery(string type)
{
var searchParams = Request.GetSearchParams();
// do something with the search params
}
[HttpGet, Route("")]
public HttpResponseMessage Query(string _query)
{
var searchParams = Request.GetSearchParams();
// do something with the search params
}
}
}
Request.GetSearchParams() 是 Sparks.Engine 的一部分,您可以在此处找到 https://github.com/furore-fhir/spark
我已将 Sparks.Engine 添加到我们的 FHIR 解决方案中,因为它已经实现了许多功能。
var searchParams = Request.GetSearchParams();
帮助解析 url 中的不同参数,并使从那里继续前进变得容易得多。
此答案的灵感来自 Brian 在该主题中的先前答案。
我目前正在尝试使用 FHIR 搜索来解决路由问题。
在网页 https://www.hl7.org/fhir/search.html 的 2.1.1.48 字符串段落中,有一节介绍了如何使用修饰符 return 包含或匹配提供的参数值的结果。
例如:
[base]/Patient?name=eve
[base]/Patient?name:contains=eve
[base]/Patient?name:exact=Eve
我从未见过 f.ex 接受带有这些自定义修饰符“?name:exact/contains”的此类 URL。开箱即用的 Web api 服务。
据我所知,在
的行里是不允许写东西的[Route("{type}/name:contains/{name}")]
public HttpResponseMessage GetContainsName(string name){
//do something
}
[Route("{type}/name:exact/{name}")]
public HttpResponseMessage GetExactName(string name) {
//do something else
}
在sqlonfhir服务器中(我相信Spark服务器也是如此)参数的处理不是通过webapi路由完成的。
我们都使用路由来提取资源名称、ID、操作(以及历史记录和版本 ID),所有其他功能都是通过从 RequestUrl 中提取内容并进行处理来手动完成的。
[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);
}
(不是完整的代码摘录——我已经剥离了处理二进制资源的代码,以及_summary参数内容处理)
此代码中的另一个值得注意的项目是,处理是在模型内完成的(因此我可以在 Web 上下文外部进行单元测试)。 CalculateBaseURI 方法可确保将请求中的 URL 应用于结果中的位置,而无需进行配置设置来告诉服务器要放在那里的内容。
在我讨论它的同时,我们也使用媒体格式化程序来解析资源内容。
这是启动 FHIR 服务器和 运行 的可能解决方案。我使用了 Sparks.Engine 中的一些代码,因此更容易使修饰符以及 "decoding" 和 url.
一起工作您将有望通过任何一种方法获得成功
这些方法应该接受 url 这样的
fhir/Patient/1
fhir/Patient?name=something
fhir/?_query="nameOfQuery"&name:contains="someName"
服务器本身的代码如下所示
namespace FHIRServer.Controllers
{
[RoutePrefix("fhir"), EnableCors("*", "*", "*", "*")]
[RouteDataValuesOnly]
public class FhirController : ApiController
{
public FhirController()
{
}
[HttpGet, Route("{type}")]
public HttpResponseMessage ResourceQuery(string type)
{
var searchParams = Request.GetSearchParams();
// do something with the search params
}
[HttpGet, Route("")]
public HttpResponseMessage Query(string _query)
{
var searchParams = Request.GetSearchParams();
// do something with the search params
}
}
}
Request.GetSearchParams() 是 Sparks.Engine 的一部分,您可以在此处找到 https://github.com/furore-fhir/spark 我已将 Sparks.Engine 添加到我们的 FHIR 解决方案中,因为它已经实现了许多功能。
var searchParams = Request.GetSearchParams();
帮助解析 url 中的不同参数,并使从那里继续前进变得容易得多。
此答案的灵感来自 Brian 在该主题中的先前答案。