How to have timing and retry policy when Apollo gateway is failing? - microservices

The Apollo Gateway module requires a list of GraphQL servers to connect to. If any of these services miss responding with a success code to the Apollo Gateway, the whole Gateway will exit with a failed status.
There should be a retry policy for when the gateway is failing. Apollo Gateway initialization so that it is managed by a retry function in case of failure.
How can I do that?

I could find the solution:
With gateway.load() we could catch the errors and do whatever we want.

Related

In AWS WebSocket API (API Gateway), can I send a message to the client in the $connect route?

When my lambda gets ivoked due to $connect route getting invoked, can I safely send a message to the connection id at this point. Or is the connection not yet fully established? Is it a better idea to use a HTTP response header?
Yes, you should be able to as you will have the client's connectionID. The docs say the connection is established when your integration execution completes.

AWS API GW always establishes WebSocket connection

I have AWS API GW in WebSocket mode with HTTP integration(not proxy mode).
The problem is that my service can return any response code for the $connect endpoint but API GW always establishes a connection with a client.
But in the documentation I see this:
Until execution of the integration associated with the $connect route is completed, the upgrade request is pending and the actual connection will not be established. If the $connect request fails (e.g., due to AuthN/AuthZ failure or an integration failure), the connection will not be made.

Unable to establish a websocket connection for GraphQL subscription

I am trying to implement a GraphQL WebSocket-based #subscription on a server (using NestJS #subscription). The server is hosted on an AWS ECS and is behind an ALB.
We currently have an AWS API GW connection via VPC-link to our ALB.
I tried to build a dedicated Websocket API GW with the same VPC link we use in the HTTP API GW.
I also tried to spin up a new NLB (Network Load Balancer) over our ECS and a new REST VPC link to be used in the dedicated Websocket API GW.
The client and server are communicating over a graphql-transport-ws sub-protocol using graphql-ws library and the communication is working fine on a localhost setup.
When running the following command on our local host I am able to establish a web socket connection:
wscat -c ws://localhost:3000/graphql -s graphql-transport-ws
When running the same against the WebSocket API GW URL
wscat -c wss://*****.execute-api.*****.amazonaws.com/**** -s graphql-transport-ws
I’m getting this:
error: Server sent no subprotocol
The error indicates a problem with the sub-protocol so when removing the sub-protocol a connection is established and I am getting a prompt:
Connected (press CTRL+C to quit)
>
However, there’s no indication of reaching the server and it seems like the connection is only made with the WebSocket API GW itself.
When I circumvent the gateway and directly connect an internet-facing NLB I'm able to establish a WebSocket connection.
I am not a super Websocket expert, but I understand WebSocket connections will be terminated by the API Gateway and cannot be used as a connection pass-through. You can forward web socket events using AWS_PROXY integration to a graphQL server backend, BUT it's not a maintained direct connection - API Gateway terminates and events towards the backend integration and will not return the integration response to the WebSocket since it is event-driven and not a connection-oriented service - hence the “error: Server sent no subprotocol” you are seeing.
So to use API GW as the WebSocket layer, you would need to build out connection management functionality somewhere to manage the event-based nature of the APIGW and send out data to the APIGW connections or adjust the integration mechanism within the graphql server to utilise the #connection functionality to send responses/notifications to WebSocket consumers.
Integrating Backend Service documentation:
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-routes-integrations.html
Sending responses to a connected client:
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-how-to-call-websocket-api-connections.html
API GW Websockets are great for building custom solutions but take some effort since you will be configuring the setup for the events.
For a GraphQL API on AWS - I would recommend taking a look at AppSync, which is an AWS Managed GraphQL service - it handles GraphQL subscriptions via WebSockets natively and with zero additional code and its highly scalable out of the box and would simplify the GraphQL hosting burden of an ECS based solution.
I suspect there may be a lot of other reasons for the need to build out using existing GraphQL on ECS, so understand it's not always possible to pivot to something like AppSync. I feel the NLB solution you tried is okay within the existing ECS backend landscape and, as you have noted, is connection-oriented (via NLB), so will achieve the outcome you are after.

Handling "resolver returned no addresses" grpc error

I've faced a problem with error handling on my gRPC client. Shortly: I've got gRPC client and server both running in Kubernetes. Client makes synchronous calls to server to retrieve some data. Everything goes fine, but some time ago the client received an error rpc error: code = Unavailable desc = resolver returned no addresses. I've restarted the POD and it has reconnected without any problems.
After googling and looking into the gRPC balancer source code I've found that this error returns when the balancer cannot get the IP from a DNS (thats quite logical). It seems to be effects of Kubernetes PODs rebalancing or so.
But the question is how to handle this error properly? GRPC client has built in reconnection mechanism but it's not triggered in that situation. Of course I can catch this error, close existing connection and make a dial again, but I don't want to build a bicycle if there is more correct way to handle it.
Thank you!

How to respond an error in a Parse Cloud Function and prevent retries?

Parse clients automatically retries network calls because of, you know, network.
I have a Parse Cloud Function that may return an error.
In that case I don't want the client to retry the call, because it'll fail again and again until the client stop trying.
Is there any way I can prevent the retry if the function was properly handled and an error was sent?
If there's no way, how bad it is to send a success with an error flag?
Clients will retry only if the error is due to network connectivity or server availability issues. If the error is any other type of error, as could happen when a Cloud function returns an error, or a save is rejected, the client will not retry. In general it does not make sense to retry here because retrying will rarely result in a successful response when the error is not connectivity/server related.
You may use error codes better on client to stop retries. This include network error code as well.

Resources