Ruby on Sinatra:根据参数模拟请求

Ruby on Sinatra: Imitate a request based on a parameter

我目前正在开发一个基于 Sinatra 的 Ruby API。此 API 主要从支持外部 API 集成的现有社交平台接收 GET 请求。

社交平台触发如下格式的GET请求(仅显示相关参数):

GET /{command}

参数:命令文本

其中 text 是用户输入的字符串。

在我的例子中,params[:text] 实际上是一系列命令,由 space 分隔。我想要实现的是,例如: If params[:text]="corporate finance"

然后我希望我的 API 将请求解释为 GET 请求 /{命令}/corporate/finance 而不是使用字符串作为包含请求其余部分的参数来请求 /{command}。

我这边可以实现吗?社交平台的初始请求不能改变。

编辑:我认为解释我想要实现的目标的更好方法如下:

GET /list?text=corporate finance

应该和

一样endpoint/route
GET /list/corporate/finance

这不得影响来自社交平台的初始 GET 请求,因为它希望向用户显示包含文本的响应。有没有一种简洁的最佳实践方法?

get "/" do {
  text = params[:text].split.join "/"
  redirect "#{params[:command]}/#{text}"
end

可能会成功。虽然没有检查。

编辑:好的,之前的过滤器很愚蠢。基本上你也可以路由到“/”然后重定向。或者,甚至更好:

get "/:command" do {
  text = params[:text].split.join "/"
  redirect "#{params[:command]}/#{text}"
}

有很多方法可以实现这一点。您应该检查 sinatra 文档的路由部分 (https://github.com/sinatra/sinatra)

three 的回答应该可以解决问题,并且要绕过每个请求都会调用过滤器的事实,这样的条件应该做:

before do
  if params[:text]
    sub_commands = params[:text].split.join "/"
    redirect "#{params[:command]}/#{sub_commands}"
  end
end

我已经在演示应用程序中对其进行了测试,它似乎工作正常。

抱歉,我完全误解了你的问题,所以我用这个替换我的答案:

require 'sinatra'

get '/list/?*' do
  "yep"
end

像这样,下面的路线都是一样的 您需要为每个命令添加例程或用 * 替换命令,并根据情况确定输出。 用户输入的params可以通过params hash引用。

http://localhost:4567/list
http://localhost:4567/list/corporate/finance
http://localhost:4567/list?text=corporate/finance

解决方法就是调用!方法。

我使用正则表达式来拦截匹配 /something 且没有其他参数(即 /something/something else)的调用。我觉得这一步可以做得更优雅

从那里开始,我拆分了我的命令:

get %r{^\/\w+$} do
  params[:text] ? sub_commands="/"+params[:text].split.join("/") : sub_commands=""
  status, headers, body = call! env.merge("PATH_INFO" => "/#{params[:command]}#{sub_commands}")
  [status, headers, body]
end

这正是我所需要的,因为它激活了正确的端点,就好像 URL 是以通常的格式输入的,即 /command/subcommand1/subcommand2 等.