通常,对于我们的简单脚本,我们将 Faraday.default_adapter 设置在顶部一次,但是在与喜欢重定向的 Github 合作时,我们必须使用 faraday_middleware(也不必使用)来跟踪重定向,这需要我们做一个块(我假设)我认为如果 Faraday 假设处理程序应该设置为 Faraday.default_adapater 如果它没有在块中设置使用会更好,这样可以节省一些编码和冗余代码 IMO。
不确定这一点,但会让它打开。 默认堆栈是 UrlEncoded + default_adapter。 如果您要定义自己的堆栈,那么您应该 100% 定义它,包括适配器。 但确实我最常使用 default_adapter,所以它也可能是一个默认值。
我正在考虑重构法拉第适配器,使它们成为端点而不是中间件(根据 #47)。 此功能可能是该更改的一部分。
:+1: 这是今年第二次咬我。 你会认为我会学习。 如果能修好就好了。
妥协: Faraday.with_default_stack()
,因此我们倾注了灵魂,只是第一次尝试使用法拉第不必了解“默认堆栈”的任何信息,就可以遵循重定向。 合理的?
@jbrains是的,我意识到这对用户不友好。 如果您没有安装适配器,或者将其安装在错误的位置,我们可能会提出描述性错误。
我在我的项目中这样做了:
def faraday_with_default_adapter(base, &block)
Faraday.new(base) { | connection |
yield connection
connection.adapter Faraday.default_adapter
}
end
我知道您不想支持所有排列,但似乎几乎每个人最终都会这样做。 :) 如果我知道如何添加UrlEncoded
位(我还没有碰到过),那么我会在这里添加它。
带有描述性错误的lint
样式检查肯定会有所帮助。 谢谢。 即便如此,一点点pokayoke会帮助我们更多。
将来我会考虑向您发送拉取请求。 同时,谢谢。
当我尝试上传并且没有指定默认适配器(我假设它已经设置,因为它是默认适配器)时,这消耗了几个小时的工作。 我一直在调试和检查响应/请求对象,完全没有问题,除了我错过了可怕的默认适配器线。
我认为这至少应该记录在某个地方的 README 中,或者至少警告我我需要一个明确的适配器。
谢谢!
这让我今天也有以下例子:
conn = Faraday.new(url: "http://www.example.com") do |faraday|
faraday.response :json, content_type: /\bjson$/
end
response = conn.get("stuff")
当 faraday_middleware 尝试获取nil
时的响应标头时,该错误会弹出。 有点误导。 是否已就处理此问题的“最佳方式”做出决定?
我很乐意提交 PR
不需要PR。 我们将尝试在下一个版本中解决这个问题。
谢谢你,@mislav。
是啊,我昨天浪费了一个小时追这个。 很高兴看到修复正在进行中。 下一个版本可能何时登陆? 最后一个是一月,这似乎是一个非常长的时间。
2014 年 10 月 2 日星期四下午 5:49,John Carney通知@github.com
写道:
下一个版本可能何时登陆? 最后一个是一月,这似乎
很长一段时间。
由于 0.8 和 0.9 应该是功能冻结的,对此的修复很可能是
仅在 1.0 中出现,我不确定它何时会出现。
对于一个简单的中间立场,这又如何:如果在没有适配器的情况下尝试发出请求,则会引发异常。
还是有没有适配器“发出请求”的用例?
2014 年 10 月 3 日星期五下午 2:07,John Bachir [email protected]
写道:
对于一个简单的中间立场,这又如何:如果试图做出
没有适配器时的请求,会引发异常。
我们如何检测是否安装了适配器?
请注意,某人实现的自定义适配器不一定具有
继承 Faraday::Adapter。
啊,我明白了。 因为适配器是其他中间件的兄弟,并且唯一要测试的 api 是标准机架 api,所以无法识别中间件是否是 http 适配器。 :悲伤长号:
如果实现了这一点,#496 中的更改可能会被还原(如果它们首先被合并)。
对此+1。 至少,没有指定适配器的错误,或者如果没有指定,最好使用default_adapter
。
这个名字令人困惑,当您必须添加中间件时,您希望只添加中间件并将default_adapter
保留在适当的位置。
我们最终根本没有适配器,这很愚蠢。 你永远不想要那个...
我只是想确保每个人都知道我们正在内部讨论管理这个问题的策略。
我知道这听起来很容易检查,但正如@mislav已经解释的那样,我们目前有一个与人们必须将适配器添加到中间件堆栈的自由相关的问题。
事实上,目前,“适配器”只不过是一个中间件,就像其他任何一个中间件一样,执行请求。
现在,当您定义自己的中间件堆栈时,我们失去了从其他中间件检测适配器的能力,除非您在构建连接时使用#adapter
方法。 不幸的是,目前并不强制使用它,因此无法检测适配器。
凉爽的! 感谢您的提醒:)
2016 年 11 月 14 日下午 2:45,Mattia [email protected]写道:
我只是想确保每个人我们都在内部讨论策略
管理这个。
我知道这听起来很容易检查,但是
@mislav已经解释过我们在
与自由相关的时刻人们必须将适配器添加到
中间件堆栈。
事实上,目前“适配器”只不过是一个中间件,比如
任何其他,执行请求。
现在,当您定义自己的中间件堆栈时,我们失去了
从其他中间件检测适配器,除非您使用#adapter
建立连接时的方法。 不幸的是,它的使用不是
目前是强制性的,因此无法检测适配器。—
您收到此消息是因为您发表了评论。
直接回复此邮件,在 GitHub 上查看,或静音线程。
https://v2.developer.pagerduty.com/docs/authentication
因此 ruby+faraday 的 PagerDuty API 文档展示了这种行为; 如果你只使用他们的代码,它就行不通。 (除非他们修复它,他们现在可能会修复它,因为我指出缺少适配器。)
老实说,我的建议是:
如果我调用“conn.get”,而 conn 没有适配器,请引发异常告诉我. 当前的行为是立即返回,但没有将事物设置为法拉第描述的调用 get 所产生的状态。 例如,“.status”仍然为零。 这真是令人惊讶的行为! 我会说“我什么都做不了,因为我不知道你想让我做什么”可能会产生某种诊断。
嗨@seebs ,我知道这听起来很傻,但我解释了为什么这不像我之前的评论中出现的那么容易:
当您定义自己的中间件堆栈时,我们失去了从其他中间件检测适配器的能力,除非您在构建连接时使用 #adapter 方法。 不幸的是,目前并不强制使用它,因此无法检测适配器。
我一直在试图追踪发生的事情,但我遗漏了一些东西。
如果你做了很多人都会做的显而易见的事情,并且没有指定适配器,那么当你调用 get 时,你最终会进入 rack_builder 的 build_response,它会执行 app.call。 而且我...实际上不确定它的去向,因为我看不到应用程序的设置位置。
所以我想我想知道的是,如果你从不做“适配器:foo”,最终会得到什么?
一个简单的解决方案:
def 初始化(处理程序 = [])
@handlers = 处理程序
如果block_given?
...我认为这会起作用(-ish)?
或者,在 build(&Proc.new) 之后,检查 self.adapter 是否已设置。
尽管adapter :foo
是设置适配器最常用的方法,但还有其他方法可以做到这一点。
#adapter
实际上只是一个助手,但您可以使用#use
将适配器放入堆栈:
conn = Faraday.new(url: "http://www.example.com") do |faraday|
faraday.response :logger
faraday.use Faraday::Adapter::NetHttp
end
那么现在的适配器是什么? 只不过是一个执行调用并将结果存储在env
中的中间件。 这就是为什么我们不能简单地依赖被调用的#adapter
方法。 我们不能依赖作为适配器工作的中间件从Faraday::Adapter
继承,因为这也不是必需的。
唯一的解决方案是使用 Faraday 1.0 版本强制使用#adapter
方法,或者假设它会被使用并在未调用该方法时将默认适配器压入堆栈。
我们仍在内部讨论哪种方法是最好的解决方案,因为我们最终会让人们在更新后得到意想不到的结果。
这是很多人第一次使用法拉第时发生的事情,我同意,但是当你运行bundle update
后在你的生产系统上发生这种情况时肯定会更糟:)
我想我不明白的是......如果您从未设置适配器,最终会处理调用并存储结果? 我认为,如果您选择了一个适配器,那么有一个调用会使用适配器的 call() 方法。 如果您还没有选择适配器,实际执行的是什么代码?
这是我选择适配器的地方,没有使用#adapter
方法。
faraday.use Faraday::Adapter::NetHttp
从我之前的评论中提取我的片段并尝试一下,它会起作用的。
问题是您可以通过多种方式将适配器推送到堆栈中,一旦它在那里,它将在请求中使用(调用#call
方法)
抱歉,我显然不清楚。 我知道您可以通过多种方式选择适配器。
但是考虑一下常见的新手错误,即不选择适配器,然后调用 conn.get(...)。 除了“没有任何影响”之外,实际上最终会发生什么?
我试图追踪电话,但无法弄清楚最终会发生什么。 看起来 Connection 将定义一个调用 run_request 的默认 get。 这反过来又调用了 build_request 和 build_response,我认为这最终会出现在 rack_builder 的 build_response() 中,它正在调用 app.call(),并且看起来 app 正在生成一个处理 call() 的 Response 对象。 但后来我感到困惑。 我什至没有看到 Response 定义了 call() 方法,而且我无法弄清楚实际调用 call() 方法的最终结果。
我有点假设有些东西有一个调用方法,它会被调用。 如果您选择了一个适配器,您将获得该适配器的调用方法。 如果没有选择适配器,那么实际执行的调用方法是从哪里来的呢?
设置好请求和响应后, Connection
遍历每个中间件并在它们上调用call(env)
方法,其顺序与填充堆栈的顺序相同。
它在“普通中间件”和适配器之间没有任何区别,它只是假设中间件之一是适配器。 如果堆栈中没有“适配器中间件”,则将调用所有其他中间件( call
方法),但它们都不会有效地执行请求(即适配器角色)。
这意味着响应将缺少由“适配器中间件”填充的状态、正文和所有其他字段。
我知道这不是很容易,但我希望现在更清楚了😅
啊哈! 那是我无法理解的。 我没想到他们都会提供 call() 函数。
如果在调用所有内容后,如果未设置状态,代码会引发异常怎么办? “StatusNotSetException:未设置状态。很可能,您的中间件没有指定适配器来实际进行网络获取。”
我真的很想看到这个修复!
已在 #750 @iMacTia中修复 - 你会关闭它吗?
@olleolleolle是的,好点! 我认为这将通过提及它来自动关闭:(
好像从来没有发布过? 有没有机会在 1.0 之前看到次要版本? :别嚼舌根:
@franzliedke你是对的,这目前包含在 v1.0 中,我同意它在很久以前就被合并了😅。
不过,我们在 v1.0 方面取得了很大进展,我想说我们已经非常接近完成它了。
多给我们一点时间,等待是值得的😃
很高兴听到!
很抱歉遇到了一些要求 - 我知道开源会带来多大的压力。 感谢伟大的软件!
一点也不@franzliedke !
感谢您的推动,我们应该尽快瞄准并发布 v1.0。
如果您还没有,请观看 repo,这样您就不会错过发布 👍
最有用的评论
对此+1。 至少,没有指定适配器的错误,或者如果没有指定,最好使用
default_adapter
。