当使用 Octokit 向 graphql 端点发送请求时,如何设置自定义Accept:
标头以打开“预览”API?
我需要做一个 GraphQL 查询,它是 API 预览的一部分,所以它需要我将Accept
标头设置为application/vnd.github.starfox-preview+json
(请参阅GitHub API 文档)。
我在 Rails 项目中使用 Octokit (4.15.0),并且使用 v3 和 v4 (GraphQL) API 成功地进行了正常查询(不是预览模式)。
对于普通查询(不是 API 预览),我的代码看起来像这样,并且可以完美运行。在这里,该方法graphql_query_string
形成了正确的查询字符串,并且是 Octokit对象github_machine_user
的一个实例。Client
有效的代码(当Accept:
不需要自定义标头时)
def perform_graphql_query(repo_name, org_name, after="")
graphql_query_string = graphql_query(repo_name, org_name, after)
options = { query: graphql_query_string }.to_json
github_machine_user.post '/graphql', options
end
这导致使用默认Accept
标头,这显然是"application/vnd.github.v3+json"
(更多关于我如何在下面了解这一点。)
我尝试了几种添加自定义Accept:
标题的方法,但没有一种方法有效。这是我尝试过的:
不成功的尝试#1:
def perform_graphql_query(repo_name, org_name, after="")
graphql_query_string = graphql_query(repo_name, org_name, after)
options = {:query => graphql_query_string,
:headers => {:accept => "application/vnd.github.starfox-preview+json"}
}.to_json
github_machine_user.post('/graphql', options)
end
不成功的尝试#2:
def perform_graphql_query(repo_name, org_name, after="")
graphql_query_string = graphql_query(repo_name, org_name, after)
options = {
:query => graphql_query_string,
:accept => "application/vnd.github.starfox-preview+json"
}.to_json
github_machine_user.post('/graphql', options)
end
这些都没有设置正确的标题。从post方法和底层请求方法的源代码中,我希望这可以工作。这就是它们的样子。
# Make a HTTP POST request
#
# @param url [String] The path, relative to {#api_endpoint}
# @param options [Hash] Body and header params for request
# @return [Sawyer::Resource]
def post(url, options = {})
request :post, url, options
end
def request(method, path, data, options = {})
if data.is_a?(Hash)
options[:query] = data.delete(:query) || {}
options[:headers] = data.delete(:headers) || {}
if accept = data.delete(:accept)
options[:headers][:accept] = accept
end
end
是我,还是 Octokit 中的错误?
我可以告诉标题没有被设置,不仅仅是因为我得到了指示的结果Field 'project' doesn't exist on type 'AddedToProjectEvent'
,因为我还遵循了 Octokit 文档中关于打开调试信息的建议,并且我可以看到我的请求中的标题。
以下是它们的显示方式(除编辑凭据外)
I, [2020-07-24T12:26:37.989030 #64350] INFO -- request: POST https://api.github.com/graphql
I, [2020-07-24T12:26:37.989109 #64350] INFO -- request: Accept: "application/vnd.github.v3+json"
User-Agent: "Octokit Ruby Gem 4.15.0"
Content-Type: "application/json"
Authorization: "token REDACTED_FOR_STACK_OVERFLOW_POST"
所以我设置接受标头的请求没有得到尊重。
我确实验证了使用curl
,我能够通过传递正确的Accept
标头使查询正常工作。因此,graphQl 查询已正确形成,并且当 Accept 标头正确放入查询时,一切都很好。但我似乎无法弄清楚如何让 Octokit 在设置 Accept 标头时尊重我的意愿。我什至查看了源代码,看来我正在做的事情应该有效。
任何人都可以帮忙吗?
更新:也作为问题发布在 Octokit 的 GitHub Repo 上。
更新 #2:我尝试删除to_json
. 不幸的是,这给出了如下所示的堆栈跟踪。
如果我删除to_json
然后只通过{:accept => "application/vnd.github.starfox-preview+json"}
然后它确实设置了正确的标题。但是,如果尝试包含:query
在该散列中,则会导致以下错误,除非我to_json
在散列上有 。我只是似乎无法获胜。
NoMethodError undefined method `each' for #<String:0x00007fb05be10b00>
/Users/pconrad/.rvm/gems/ruby-2.6.5/gems/faraday-1.0.0/lib/faraday/utils/params_hash.rb:28:in `update'
/Users/pconrad/.rvm/gems/ruby-2.6.5/gems/sawyer-0.8.2/lib/sawyer/agent.rb:99:in `block in call'
/Users/pconrad/.rvm/gems/ruby-2.6.5/gems/faraday-1.0.0/lib/faraday/connection.rb:489:in `block in run_request'
/Users/pconrad/.rvm/gems/ruby-2.6.5/gems/faraday-1.0.0/lib/faraday/connection.rb:506:in `block in build_request'
/Users/pconrad/.rvm/gems/ruby-2.6.5/gems/faraday-1.0.0/lib/faraday/request.rb:55:in `block in create'
/Users/pconrad/.rvm/gems/ruby-2.6.5/gems/faraday-1.0.0/lib/faraday/request.rb:54:in `tap'
/Users/pconrad/.rvm/gems/ruby-2.6.5/gems/faraday-1.0.0/lib/faraday/request.rb:54:in `create'
/Users/pconrad/.rvm/gems/ruby-2.6.5/gems/faraday-1.0.0/lib/faraday/connection.rb:502:in `build_request'
/Users/pconrad/.rvm/gems/ruby-2.6.5/gems/faraday-1.0.0/lib/faraday/connection.rb:484:in `run_request'
/Users/pconrad/.rvm/gems/ruby-2.6.5/gems/faraday-1.0.0/lib/faraday/connection.rb:279:in `post'
/Users/pconrad/.rvm/gems/ruby-2.6.5/gems/sawyer-0.8.2/lib/sawyer/agent.rb:94:in `call'
/Users/pconrad/.rvm/gems/ruby-2.6.5/gems/octokit-4.18.0/lib/octokit/connection.rb:156:in `request'
/Users/pconrad/.rvm/gems/ruby-2.6.5/gems/octokit-4.18.0/lib/octokit/connection.rb:28:in `post'
/Users/pconrad/github/project-anacapa/anacapa-github-linker/app/jobs/course/course_github_repo_get_sdlc_events.rb:105:in `perform_graphql_query'
更新#3:在下面添加了我自己的答案,但看起来很老套。我不得不调用一个私有方法,这是不应该做的,而且绝对不应该“必须做”。所以,还是希望有更好的解决方案。