当我的请求URL有查询字符串时,如何使用Grapevine编写正则表达式来路由流量?

时间:2015-11-09 22:25:42

标签: c# rest grapevine

我正在使用Grapevine并且我想要路由具有查询字符串的请求流量,并且我不太了解正则表达式以找出它无法正常工作的原因。

e.g。

http://localhost:1234/service/function?param1=1&param2=2

我将RESTRoute定义为:

[RESTRoute(Method = HttpMethod.GET, PathInfo = @"^/service/function\?\D+$")]
public void HandleFooRequestString(HttpListenerContext context)
{
    PrintRequest(context);
    this.SendTextResponse(context, "foo is a success!");
}

但是发送到网址的流量不是那种方法。我做错了什么?

1 个答案:

答案 0 :(得分:2)

这是一个pretty common question,并对Grapevine路线图产生了一些变化。

Grapevine 3.1.0 +

在最新版本的Grapevine中,在正则表达式模式匹配之前,会从URL中删除查询字符串,因此这不再是问题。

此外,版本4中的路由正在更新以匹配Node/Express routing mechanism,因此如果您愿意,可以选择不使用正则表达式。但是,这个版本仍处于规划阶段。

Grapevine 3.0.x

虽然GET请求包含query string参数肯定不常见,但我们首先要确保使用正确的URI设计。引用O'Reilly's RESTful Web Services,第233页,标题 URI设计(强调我的):

  

设计URI时,使用路径变量分隔层次结构的元素,或通过有向图分隔路径。示例:/weblogs/myweblog/entries/100从一般到具体。从博客列表到特定博客,到该博客中的条目,再到特定条目。每个路径变量在某种意义上都是#34;内部"上一个。

     

使用标点符号在同一层次结构中分隔多个数据。当项目的顺序很重要时使用逗号,就像纬度和经度一样:/Earth/37.0,-95.2。如果订单不重要,请使用分号:/color-blends/red;blue

     

仅使用查询变量来建议插入算法的参数,或者当其他两种技术失败时。如果两个URI仅在其查询变量上有所不同,则意味着它们将不同的输入集合放入相同的基础算法中。

这里最重要的一点是,我们的URI一般来说应该只使用查询字符串将参数传递给算法。实际上,如果我们期望在我们的方法中使用查询字符串参数,那些应该通过请求被路由到的方法进行验证,并且我们的PathInfo正则表达式应该反映接收这些参数的可能性。

示例:何时不使用查询字符串

假设您想要根据特定的数字用户ID请求用户数据,请说 632 。这种情况可能很容易使用查询字符串,但最好不要这样做。

  • 不太正确的URI:/user?id=632
  • 更正确的URI:/user/632

更正确的URI的RESTRoute将如下所示:

[RESTRoute(Method = HttpMethod.GET, PathInfo = @"^/user/\d+$")]
public void GetUser(HttpListenerContext context)
{
    var userid = context.RawUrl.GrabFirst(@"^/user/(\d+)$");
    // you got your user id, do something
}

示例:正确使用查询字符串

如果你想创建一个将两个整数相乘的REST路由,那么 - 假设该URI假设代表资源,而不是资源上的操作 - 使用查询字符串可能更合适。

  • 可能不太正确的URI:/2/product/3
  • 可能更正确的URI:/product?x=2&y=3

可能更正确的URI的RESTRoute将如下所示:

[RESTRoute(Method = HttpMethod.GET, PathInfo = @"^/product")]
public void MultiplyTwoIntegers(HttpListenerContext context)
{
    var x = context.Request.QueryString["x"];
    var y = context.Request.QueryString["y"];

    // Verify the inputs and do the math.
}

请注意,PathInfo正则表达式省略了尾部$,它通常表示字符串的结尾,我们让路由方法处理传递的参数。如果我们真的想成为一名坚持者,我们也可以这样写:

[RESTRoute(Method = HttpMethod.GET, PathInfo = @"^/product\?.+$")]

这可以确保它至少看起来可能会有一些参数出现在查询字符串中,但是因为我们无论如何要进行检查,所以并不是必需的。