andyrichardson / subscriptionless

GraphQL subscriptions (and more) on serverless infrastructure
MIT License
93 stars 3 forks source link

Add sendMessage handler #8

Open reconbot opened 3 years ago

reconbot commented 3 years ago

I'm using architect for my dev environment and infrastructure management. The dev environment has a api gateway, ddb, lambda and sns, simulators. They're incredibly enjoyable to use locally. However, sending websocket messages in the dev environment doesn't work the same way as it does it production and I need to use it's method instead of the AWS Manager object directly.

I'd like to be able to provide my own async function to send messages, so I can use subscriptionless with architect.

The hook could be used to modify the message or prevent sending. I made up some trite examples of why you might want it, but I bet there are real use cases besides the dev server. And of course the simple case of "if the hook is set, just use that hook" works for me.

const instance = createInstance({
  /* ... */
  onSendMessage: async ({ message }) => {
    // prevent sending
    if (containsSensitiveData(message)) {
       return false
    }
    // send through another channel?
    if(highPriority(message)){
       await fastSend(message)
    }
    // send normally
    return message
  },
});

Happy to do the PR (or not) if this is something you'd add to the project.

reconbot commented 3 years ago

This turned out to be pretty straightforward thanks to the structure of things. https://github.com/andyrichardson/subscriptionless/compare/master...reconbot:reconbot/onSendMessage will make a pr if you're interested in it.

reconbot commented 3 years ago

I did some more research and experimenting.

I think I can make some changes to the arc sandbox to support the ApiGatewayManagementApi directly, however it would need a custom endpoint configuration as arc can only provide http in development and the way you make the endpoint uri out of the domain and stage in the event assumes https. (You don't specify a protocol but it seems to figure it out.)

It seems having a custom management endpoint isn't out of the question;

The Amazon API Gateway Management API allows you to directly manage runtime aspects of your deployed APIs. To use it, you must explicitly set the SDK's endpoint to point to the endpoint of your deployed API. The endpoint will be of the form https://`[api-id].execute-api.[region].amazonaws.com/[stage]`, or will be the endpoint corresponding to your API's custom domain and base path, if applicable.

So if it makes more sense a configurable endpoint might do the trick.

andyrichardson commented 3 years ago

Thanks for taking the time to make this suggestion!

So if it makes more sense a configurable endpoint might do the trick.

Best case scenario would probably be exactly this - the reason being, there are likely going to be more and more occasions where interfacing with the AWS API will take place:

If you use a local endpoint, regardless of how the implementation details change, you'll always be able to mock/implement a local environment however you need. I couldn't necessarily give that guarantee if we were to create an escape hatch for each interaction with AWS (and there's also the argument of differing logic between dev/deployed environments).

In terms of how this would integrate with Architect, I don't know much about it but Serverless have managed to get this working using local endpoints. Might be worth opening an issue with them also!