0

I am trying to deploy a graphql server in AWS over websocket connection. I have deployed a websocket apigateway which has two routes, $connect and $default. Each route points to a lambda implemented in golang. I am using LAMBDA_PROXY.

I am using github.com/graph-gophers/graphql-go library to support resolvers in the lambda side. Since the apigateway provides websocket connection, I don't need any websocket transport inside my lambda.

What I am trying to do is to receive the subscribe request from clients and parse the request body and save the connection and subscribed topic in a database.

But I can't figure out how to make it work without a real ws grahpql transport in the lambda.

Below is the code in lambda for $connect route,

func (h *Handler) GraphqlSubscriptionHandler(ctx context.Context, event events.APIGatewayWebsocketProxyRequest) (events.APIGatewayProxyResponse, error) {
    log.Println("event.RequestContext ConnectionID:", event.RequestContext.ConnectionID)
    log.Println("body", event.Body)
    log.Println("PathParameters", event.PathParameters)
    log.Println("QueryStringParameters", event.QueryStringParameters)
    return events.APIGatewayProxyResponse{Body: "", StatusCode: 200}, nil
}

func main() {
   lambda.Start(GraphqlSubscriptionHandler)
}

when the client sends a subscription request like below:

subscription event {
    event(on:"xxxx") {
      message
    }
  }

I can see below logs in $connect lambda but the $default route lambda is not triggered.

event.RequestContext ConnectionID: dbmemc7FywMCEpQ=
body
PathParameters map[]
QueryStringParameters map[]

In above log, I can only get connectionId from the client but the body is empty. I think it is correct because this is $connect route which only handle connection.

The problem is more about why $default route doesn't receive any requests. Below is the client side which is using apollo client:

const { ApolloClient } = require('apollo-client');
const { InMemoryCache } = require('apollo-cache-inmemory');
const { WebSocketLink } = require('apollo-link-ws');
const { SubscriptionClient } = require('subscriptions-transport-ws');
const ws = require('ws');
const gql = require('graphql-tag');

const wsLink = new WebSocketLink(
  new SubscriptionClient(
    'wss://xxxx.execute-api.ap-southeast-2.amazonaws.com/dev',
    {
      reconnect: true,
    },
    ws
  )
);

const client = new ApolloClient({
  link: wsLink,
  cache: new InMemoryCache(),
});

const s = client.subscribe({
  query: gql`
  subscription event {
    event(on:"xxxx") {
      message
    }
  }
  `,
});

s.subscribe({
  next: ({ data }) => console.log(data),
  error: (err) => console.error(err),
});

Joey Yi Zhao
  • 37,514
  • 71
  • 268
  • 523
  • This might be an issue in request template. See this question, you may get some hint - https://stackoverflow.com/questions/70738217/aws-api-gatewat-websocket-request-templates-body-of-request-after-transformatio – Ankush Jain Dec 20 '22 at 06:35
  • I am using lambda proxy which doesn't have any template – Joey Yi Zhao Dec 20 '22 at 06:44

0 Answers0