Curl/GraphQL 命令失败,返回 200
Curl/GraphQL command failing with 200
我正在尝试编写一个 shell 脚本来针对 GraphQL API 执行 curl
并且我之前从未与 GQL 进行过交互。我遇到了一些奇怪的错误,虽然我知道这个社区无法访问 GQL 服务器,但我希望有人可以查看脚本并确保我没有做任何公然错误的事情 syntax-wise(两者在 shell 脚本层以及 GQL 查询本身)。
我的脚本:
#!/bin/bash
BSEE_WEB_SERVER_DNS=https://mybsee.example.com
BSEE_API_KEY=abc123
siteId=1
scanConfigId=456
runScanQuery='mutation CreateScheduleItem { create_schedule_item(input: {site_id: "$siteId" scan_configuration_ids: "$scanConfigId"}) { schedule_item { id } } }'
runScanVariables='{ "input": "site_id": $scanId }}'
runScanOperationName='CreateScheduleItem'
curl -i --request POST \
--url $BSEE_WEB_SERVER_DNS/graphql/v1 \
--header "Authorization: $BSEE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"query":"$runScanQuery","variables":{$runScanVariables},"operationName":"${runScanOperationName}"}'
当我 运行 脚本关闭终端时的输出:
HTTP/2 200
<OMITTED RESPONSE HEADERS>
{"errors":[{"message":"Invalid JSON : Unexpected character (\u0027$\u0027 (code 36)): was expecting double-quote to start field name, Line 1 Col 38","extensions":{"code":3}}]}%
出于安全和简洁的原因,我省略了 HTTP 响应 headers。
我想知道我对 quotes/double-quotes 的使用是否存在某种错误,或者 GQL 查询本身(通过 curl)的性质是否有任何不符合任何人的地方。
我与管理服务器的团队确认 HTTP 200 OK 响应代码是正确的。 200 表明对 GQL API 的请求成功,但 GQL 正在响应此错误以指示 query
本身不正确。
我们需要修改 GraphQL 位并修复 bash 字符串引号。
runScanQuery GraphQL 操作
修复 GraphQL 语法。使用 GraphQL operation name CreateScheduleItem
with variables $site_id
in the arguments input: { site_id: $siteId, scan_configuration_ids: $scanConfigId
:
mutation CreateScheduleItem($site_id: String!, $scanConfigId: String!) {
create_schedule_item(
input: { site_id: $siteId, scan_configuration_ids: $scanConfigId }
) {
schedule_item {
id
}
}
}
运行扫描变量:JSON
我们的突变需要两个变量,GraphQL 会将其代入 CreateScheduleItem($site_id: String!, $scanConfigId: String!)
。将 GraphQL 变量提供为 JSON。这是 bash 变量替换后的预期输出:
{ "$site_id": "1", "$scanConfigId": "456" }
正确引用 bash
最后,将输入翻译成 bash-friendly 语法:
runScanQuery='mutation CreateScheduleItem($site_id: String!, $scanConfigId: String!) { create_schedule_item(input: {site_id: $siteId scan_configuration_ids: $scanConfigId}) { schedule_item { id } } }'
runScanVariables='{"$site_id":"'"$siteId"'","$scanConfigId":"'"$scanConfigId"'"}' # no spaces!
runScanOperationName='CreateScheduleItem'
data='{"query":"'"$runScanQuery"'","variables":'$runScanVariables',"operationName":"'"$runScanOperationName"'"}'
检查我们的 bash 格式。将终端输出粘贴到 code-aware 编辑器中,例如 VSCode。期待编辑器正确解析输出。
echo $runScanQuery # want string in graphql format
echo $runScanVariables # want JSON
echo $data # want JSON
编辑:添加一个 public API 示例
这是使用 public 星球大战 API 的完整工作示例:
#!/bin/bash
filmId=1
data='{"query":"query Query($filmId: ID) { film(filmID: $filmId) { title }}","variables":{"filmId":"'"$filmId"'"}}'
curl --location --request POST 'https://swapi-graphql.netlify.app/.netlify/functions/index' \
--header 'Content-Type: application/json' \
--data "$data"
回复 {"data":{"film":{"title":"A New Hope"}}}
。
在 GraphQL 中总是有 200 个状态码是正常的;客户端必须检查响应正文以查找失败。
原因很简单:在 REST 中,http 是协议的一部分,状态码具有语义,但 在 GraphQL 中,http 不是协议的一部分,你可以让 GraphQL 超过服务器传输协议:
服务器告诉您某些事情(甚至失败)的唯一方式就是正文。
对于你的情况,我建议你 jq 通过 bash 脚本搜索 error
属性.
解析 json
您的错误与 GraphQL 完全无关。你真的错了JSON.
错误消息显示 意外字符(\u0027$\u0027(代码 36)):期望 double-quote 开始字段名称,第 1 列第 38 行,
你可以用撇号替换转义的\u0027,你会得到
意外字符('$'(代码 36)):期望 double-quote 开始字段名称,第 1 列第 38 行,
所以它讨厌你发送给 curl 的数据中第 38 位的美元符号
data='{"query":"'"$runScanQuery"'","variables":'$runScanVariables'
^
this
首先 - JSON 中的所有字段名称和值都应该用双引号引起来,而不是单引号。
第二 - 如果你想 curl 扩展 env 变量,把它放在双引号里,而不是单引号。
我正在尝试编写一个 shell 脚本来针对 GraphQL API 执行 curl
并且我之前从未与 GQL 进行过交互。我遇到了一些奇怪的错误,虽然我知道这个社区无法访问 GQL 服务器,但我希望有人可以查看脚本并确保我没有做任何公然错误的事情 syntax-wise(两者在 shell 脚本层以及 GQL 查询本身)。
我的脚本:
#!/bin/bash
BSEE_WEB_SERVER_DNS=https://mybsee.example.com
BSEE_API_KEY=abc123
siteId=1
scanConfigId=456
runScanQuery='mutation CreateScheduleItem { create_schedule_item(input: {site_id: "$siteId" scan_configuration_ids: "$scanConfigId"}) { schedule_item { id } } }'
runScanVariables='{ "input": "site_id": $scanId }}'
runScanOperationName='CreateScheduleItem'
curl -i --request POST \
--url $BSEE_WEB_SERVER_DNS/graphql/v1 \
--header "Authorization: $BSEE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"query":"$runScanQuery","variables":{$runScanVariables},"operationName":"${runScanOperationName}"}'
当我 运行 脚本关闭终端时的输出:
HTTP/2 200
<OMITTED RESPONSE HEADERS>
{"errors":[{"message":"Invalid JSON : Unexpected character (\u0027$\u0027 (code 36)): was expecting double-quote to start field name, Line 1 Col 38","extensions":{"code":3}}]}%
出于安全和简洁的原因,我省略了 HTTP 响应 headers。
我想知道我对 quotes/double-quotes 的使用是否存在某种错误,或者 GQL 查询本身(通过 curl)的性质是否有任何不符合任何人的地方。
我与管理服务器的团队确认 HTTP 200 OK 响应代码是正确的。 200 表明对 GQL API 的请求成功,但 GQL 正在响应此错误以指示 query
本身不正确。
我们需要修改 GraphQL 位并修复 bash 字符串引号。
runScanQuery GraphQL 操作
修复 GraphQL 语法。使用 GraphQL operation name CreateScheduleItem
with variables $site_id
in the arguments input: { site_id: $siteId, scan_configuration_ids: $scanConfigId
:
mutation CreateScheduleItem($site_id: String!, $scanConfigId: String!) {
create_schedule_item(
input: { site_id: $siteId, scan_configuration_ids: $scanConfigId }
) {
schedule_item {
id
}
}
}
运行扫描变量:JSON
我们的突变需要两个变量,GraphQL 会将其代入 CreateScheduleItem($site_id: String!, $scanConfigId: String!)
。将 GraphQL 变量提供为 JSON。这是 bash 变量替换后的预期输出:
{ "$site_id": "1", "$scanConfigId": "456" }
正确引用 bash
最后,将输入翻译成 bash-friendly 语法:
runScanQuery='mutation CreateScheduleItem($site_id: String!, $scanConfigId: String!) { create_schedule_item(input: {site_id: $siteId scan_configuration_ids: $scanConfigId}) { schedule_item { id } } }'
runScanVariables='{"$site_id":"'"$siteId"'","$scanConfigId":"'"$scanConfigId"'"}' # no spaces!
runScanOperationName='CreateScheduleItem'
data='{"query":"'"$runScanQuery"'","variables":'$runScanVariables',"operationName":"'"$runScanOperationName"'"}'
检查我们的 bash 格式。将终端输出粘贴到 code-aware 编辑器中,例如 VSCode。期待编辑器正确解析输出。
echo $runScanQuery # want string in graphql format
echo $runScanVariables # want JSON
echo $data # want JSON
编辑:添加一个 public API 示例
这是使用 public 星球大战 API 的完整工作示例:
#!/bin/bash
filmId=1
data='{"query":"query Query($filmId: ID) { film(filmID: $filmId) { title }}","variables":{"filmId":"'"$filmId"'"}}'
curl --location --request POST 'https://swapi-graphql.netlify.app/.netlify/functions/index' \
--header 'Content-Type: application/json' \
--data "$data"
回复 {"data":{"film":{"title":"A New Hope"}}}
。
在 GraphQL 中总是有 200 个状态码是正常的;客户端必须检查响应正文以查找失败。
原因很简单:在 REST 中,http 是协议的一部分,状态码具有语义,但 在 GraphQL 中,http 不是协议的一部分,你可以让 GraphQL 超过服务器传输协议:
服务器告诉您某些事情(甚至失败)的唯一方式就是正文。
对于你的情况,我建议你 jq 通过 bash 脚本搜索 error
属性.
您的错误与 GraphQL 完全无关。你真的错了JSON.
错误消息显示 意外字符(\u0027$\u0027(代码 36)):期望 double-quote 开始字段名称,第 1 列第 38 行,
你可以用撇号替换转义的\u0027,你会得到
意外字符('$'(代码 36)):期望 double-quote 开始字段名称,第 1 列第 38 行,
所以它讨厌你发送给 curl 的数据中第 38 位的美元符号
data='{"query":"'"$runScanQuery"'","variables":'$runScanVariables'
^
this
首先 - JSON 中的所有字段名称和值都应该用双引号引起来,而不是单引号。
第二 - 如果你想 curl 扩展 env 变量,把它放在双引号里,而不是单引号。