Appsync is already replacing API Gateway to some extend, then why do you need to expose it via API Gateway. I know most people would be asking this question. Here is why?
As far as I understood, Appsync is GrapQL + Apollo server implementation. The API exposed supports POST request. And even the subscription request is also a post request with Websocket MQTT (AWS IoT) URL as the response. (Eg provided below)
{
"extensions": {
"subscription": {
"mqttConnections": [
{
"url": "wss://something-ats.iot.ap-northeast-1.amazonaws.com/mqtt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...",
"topics": [
".../.../subscribeToVehicleLocation/..."
],
"client": "..."
}
],
"newSubscriptions": {
"subscribeToVehicleLocation": {
"topic": ".../../subscribeToVehicleLocation/..",
"expireTime": null
}
}
}
},
"data": {
"subscribeToVehicleLocation": null
}
}
If that is the case, can we expose Appsyn endpoint via API-Gateway (POST Method)?
For simplicity, I tried with HTTP API in API-Gateway.
But for Subscribe request, I am getting a handshake exception. (Connection failed: Connection handshake error, in my angular amplify project)
Is this the right way to expose Appsync via API-Gateway? Or should I use AWS Service (In API Gateway) to Invoke Appsync?
How can I resolve this Websocket Connection handshake error in Angular Amplify Project?
PS:
I was previously able to subscribe to the data using the original Appsync URL (using AmplifyJS in Angular 7). With API-Gateway URL, I am getting this WS Handshake exception (with Amplify).
WebSocket connection to 'wss://....execute-api.ap-northeast-1.amazonaws.com/graphql?header=...&payload=e30=' failed: Error during WebSocket handshake: Unexpected response code: 400
in AWSAppSyncRealTimeProvider.js:603
Update 24-04-2020
I was able to invoke Appsync via AWS Service invoke in API-Gateway with the below settings. (Used REST Protocol provided by API Gateway)
But still, I am having the Web Socket error in Amplify
API-Gateway Configuration
Note: AWS Subdomain, is the subdomain part of Appsync API Endpoint.
Trust relationship for IAM Role
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"appsync.amazonaws.com",
"apigateway.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
IAM Role Permission
After getting expert opinions, I had finally dropped the plan of exposing Appsync
via API-Gateway
.
Appsync & API-Gateway belongs to the same hierarchy in AWS Stack. It was not a good idea to expose Appsync via API-Gateway, since, Appsync endpoint would still be public (leading to a back door).
Below are my solutions (considering Appsync
alone) for
Monetization Scope: Collect Appsync metrics/trace
logs and calculate the API Usage based on Cognito UserId or Apikey.
Usage Plan/Quota: Set up a Lambda Datasource
(in Pipeline resolver) incrementing the hit count in Redis cache (with key as Apikey and value as hit count having a custom TTL say 1 day).
If there are any better solutions, please feel free to share it.