【问题标题】:Apollo GraphQL Client formatting requests improperlyApollo GraphQL 客户端格式请求不正确
【发布时间】:2020-01-07 18:09:05
【问题描述】:

我有一个在 react native 中运行的 Apollo GraphQL 客户端。它连接到运行 graphQL 的 lambda 实例。我的问题是我正在尝试向服务器发送变异请求(尚未设置查询),并且服务器收到以下内容并声明语法错误(Expected Name, found String \"operationName\")。

当我测试 graphQL 服务器时,请求看起来像下面指定的那些。 Apollo 客户端是否没有正确格式化请求(如果是,为什么不正确)或者它是否按预期运行?

从 Apollo 客户端发送到 graphQL lambda 的正文:

{
"operationName": "createUser",
"variables": {
    "firstName": "Jane",
    "lastName": "Doe",
    "email": "jane@doe.com",
    "username": "jane_doe.com",
    "provider": "none"
    "jwt": "none"
},
"query": "mutation createUser($firstName: String!, $lastName: String!, $email: String!, $username: String!, $provider: String, $jwt: String!) { 
createUser(firstName: $firstName, lastName: $lastName, email: $email, username: $username, provider: $provider, jwt: $jwt) {
    createdAt
    __typename
}
}"}

来自 Postman 的正常请求。

mutation {
  createUser(firstName: "Jane", lastName: "Doe", email: "jane@doe.com", username: "jane_doe.com", jwt: "none", provider: "none") {
    firstName
  }
}

来自 react-native 应用的代码

// The mutation in the render function
<Mutation mutation={createUserMutation}>
  {(createUser, error) => {
    console.log('error-----------', error);
    // If there is an error throw the error
    if (error) {
      console.log('error----------', error);
    }
    if (createUser) {
      // If the response has data load the response data via the createPlayer property.
      return (
        <LoginButton
          onPress={() => {
            this.signIn(createUser);
          }}
        />
      );
    }

    // By default it is loading the result so just return loading...
    return <Text>Loading...</Text>;
  }}
</Mutation>

// The signin function called when the user presses the login button
async signIn(createUser) {
  ...
  try {
    Auth.signIn(un, password)
      .then(data => {
        ...
        this.createUserFunc(
          createUser,
          'Jane',
          'Doe',
          'jane@doe.com',
          'jane_doe.com',
          'none',
          'none'
        );
   }
   ...
}

// The create user function called from the signin function
createUserFunc = (func, firstName, lastName, email, username, provider, jwt) => {
  const newUser = {
    firstName,
    lastName,
    email,
    username,
    provider,
    jwt,
  };
  func({variables: newUser});
};

// The gql syntax mutation
const createUserMutation = gql`
  mutation createUser(
    $firstName: String!
    $lastName: String!
    $email: String!
    $username: String!
    $provider: String
    $jwt: String!
  ) {
    createUser(
      firstName: $firstName
      lastName: $lastName
      email: $email
      username: $username
      provider: $provider
      jwt: $jwt
    ) {
      createdAt
    }
  }
`;

【问题讨论】:

  • 如果您通过不同的客户端(如 GraphiQL、GraphQL Playground、Postman 或 Altair(或只是一个普通的 curl 命令)发送它),同样的突变是否有效?如果无论客户端如何请求都无法正常工作,则表明服务器而不是客户端存在问题。
  • @DanielRearden 感谢您的信息。我不知道那里有像 GraphiQL 这样的工具。我发现问题出在服务器上...现在开始调查...
  • 啊……越来越清楚了。 GQL POST 请求的格式与 GET 请求大不相同。我的服务器端依赖于我发送 GET 格式的请求(尽管在 Postman 中,我正在发布)。现在弄清楚如何让我的服务器解释 POST 格式的 GQL
  • 如果您还没有,我建议您使用apollo-server-lambda 来实现您的端点,而不是尝试直接使用核心库。
  • @DanielRearden 我让它与 apollo-server-lambda 一起正常工作。比使用核心库要容易得多!非常感谢!!!

标签: react-native lambda graphql react-apollo apollo-server


【解决方案1】:

大多数接受 HTTP 请求的 GraphQL 服务器都在监听两种不同类型的内容(用the Content-Type header 表示):application/graphql 和application/json。您的服务器似乎只收听带有application/graphql 正文的请求。

Content-Type: application/graphql 的问题在于,GraphQL execution 最多包含三个可由客户端提供的参数:

  1. 查询(必填)
  2. 查询的变量值
  3. 操作名称

这使得查询文档完全是静态的。但是如果请求的内容只是 GraphQL 查询,其他的参数就需要去别的地方了。理论上它们可以作为 GET 参数提供,但通常所有客户端都使用 JSON 格式来提供所有三个,如here 所述。

正如 Daniel 指出的那样,您可以使用 GraphQL 服务器实现作为您选择的框架/技术来为您处理。 或者,您必须自己对请求的标头做出反应(这可能是一个很好的练习,但您可能会错过库作者想到的边缘情况)。

【讨论】:

  • 不太确定,但是当我从 setContext 中删除 Content-Type: application/graphql 时,它起作用了。
猜你喜欢
  • 2019-06-19
  • 2019-06-22
  • 2019-03-12
  • 2022-12-12
  • 2020-02-01
  • 2019-07-23
  • 2019-07-19
  • 1970-01-01
  • 2019-12-31
相关资源
最近更新 更多