验证 Apollo 客户端以使 AppSync 与 @aws_subscribe 一起使用

Posted

技术标签:

【中文标题】验证 Apollo 客户端以使 AppSync 与 @aws_subscribe 一起使用【英文标题】:Authenticating Apollo client for AppSync to work with @aws_subscribe 【发布时间】:2022-01-16 10:13:17 【问题描述】:

我在 AppSync 中使用 API_KEY 身份验证,它适用于查询和突变。

很难让它与@aws_subscribe 订阅一起使用。以下是我尝试获取连接的方法:

import  WebSocketLink  from '@apollo/client/link/ws'
import  setContext  from '@apollo/client/link/context'

import 
  ApolloClient,
  InMemoryCache,
  HttpLink,
  split,
 from "@apollo/client"

import  getMainDefinition  from '@apollo/client/utilities'

import  API_URI, API_KEY, REALTIME_API_URI  from "@env"

const authLink = setContext((_,  headers ) => 
  const token = API_KEY
  return 
    headers: 
      ...headers,
      'X-Api-Key': API_KEY,
    ,
  
)

const httpLink = new HttpLink(
  uri: API_URI,
)

const wsLink = new WebSocketLink(
  uri: REALTIME_API_URI,
  options: 
    reconnect: true,
    lazy: true,
  ,
)

const link = split(
  ( query ) => 
    const  kind, operation  = getMainDefinition(query)
    return (
      kind === 'OperationDefinition'
      && operation === 'subscription'
    )
  ,
  authLink.concat(wsLink),
  authLink.concat(httpLink),
)

export const gqlClient = new ApolloClient(
  link,
  cache: new InMemoryCache(),
)
// console.log( API_URI ,  API_KEY )

据我所知,这个问题被问了很多 - 我仍然无法找到令人满意的答案。有证据表明最新的 Apollo 客户端不再与 Web 套接字的 AppSync 身份验证兼容,仍然想知道是否有某种变通方法(hack)将 API_KEY 传递给 appsync 订阅,因此它不会拒绝请求并建立联系。我真的很想避免使用 Amplify,以及自己构建 SNS pub sub。真的很好奇是否有人能够让这个更简单的用例工作并可以分享一些示例代码。

这是我在客户端中订阅的方式:

const subscription = CONST.gqlClient
      .subscribe(
        query: gql`
        subscription onSendMessage($chatUuid: String!) 
          onSendMessage (chatUuid: $chatUuid) 
            chatUuid
            createdAt
            messageUuid
            text
            updatedAt
            uuid          
        
        `,
        variables: 
          chatUuid,
        ,
      )
      .subscribe(
        next(data) 
          console.log( data )
        ,
        error( error ) 
          console.log( error )
        ,
        complete()  console.log("subs. DONE") , // never printed
      )

当我运行它时,我确实在日志中看到:

Object 
  "subscription": Subscription 
    "_cleanup": Subscription 
      "_cleanup": [Function anonymous],
      "_observer": Object 
        "complete": [Function complete],
        "error": [Function error],
        "next": [Function next],
      ,
      "_queue": undefined,
      "_state": "ready",
    ,
    "_observer": Object 
      "complete": [Function complete],
      "error": [Function error],
      "next": [Function next],
    ,
    "_queue": undefined,
    "_state": "ready",
  ,

但是在那之后什么都没有发生,没有错误消息,没有订阅消息触发突变调用。 当我在 aws 控制台中订阅此订阅时——它确实触发得很好。我只是永远无法让它在客户端应用程序中工作。

【问题讨论】:

【参考方案1】:

我想出了一个可行的解决方案。 这就像使用不同的 Apollo 客户端进行“查询”和“变异”与“订阅”一样简单。 完整的解决方案可以在这里找到: https://www.echowaves.com/post/getting-apollo-client-to-work-with-aws_subscribe

【讨论】:

Dmtry 这个解决方案还有效吗?试过了。它不工作。收到此错误。知道如何解决这个问题吗? "errors" : [ "errorType" : "BadRequestException", "message" : "不支持通过 MQTT 订阅。" ] 是的,它确实对我有用(这就是我发布解决方案的原因)。不确定 MQTT 是什么意思。也许,您正在连接到与我不同的 GraphQL 服务器?我的 GraphQL 服务器实现可以在这里找到github.com/echowaves/WiSaw.cdk

以上是关于验证 Apollo 客户端以使 AppSync 与 @aws_subscribe 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Apollo 客户端与 AppSync 一起使用?

Graphql apollo 客户端从 AppSync 返回空值

带有 apollo-angular 客户端的 Aws-appsync 订阅

如何使用订阅和 AWS AppSync 高效同步 Apollo 的缓存

AppSync 的订阅是不是仅限于一个特定的用例?

Reactjs/Apollo/AppSync Mutation 触发了两次