Closed ElliotChong closed 7 years ago
Apollo Server is a standard NPM package, so I can't think of anything that would make it hard to use with lambda. Is there anything in particular you're worried about?
With the ephemeral nature of the lambda functions state comes to mind- I'm assuming the the library would be stateless and idempotent to support clustering; however, my unfamiliarity with the library left me unsure.
Also, would multiple Lambda functions need to be registered to handle multiple paths / endpoints, or is all communication with the library done via a single /graphql endpoint?
Thanks!
@ElliotChong that depends on how you use Express/Koa/HAPI. If you add any extra routes, they'll need HTTP Gateway endpoints, I believe, but can all be handled by the same AWS Lambda function. I haven't done it yet, but I definitely also want to deploy Apollo/Saturn as a lambda function. (And put the prod build of the frontend in S3 with CloudFront, etc.)
@ElliotChong @rdrey apollo-server can be used in a stateless fashion, so I think it should be fairly straightforward to use with lambda. If either of you get it working, it would be really cool if you could document it somehow (gist or github repo) or even write a blog post about it!
FYI I have just put together a proof of concept using apollo-server with Lambda which can be found at https://github.com/skrigs/lambda-apollo-server. I'm looking at writing an inaugural blog post in the near future after I have determined some nice Lambda patterns that work with GraphQL. I created an integration module lambdaApollo similar to expressApollo. There may be some merit in pulling this into the core of the ApolloStack once it becomes more mature if the team is interested.
@skrigs That's cool, I'm looking forward to reading that blog post! If it works well, I can definitely see lambda integration becoming an integral part of apollo server.
Has anybody tried this? https://www.npmjs.com/package/lambda-express
I'm experimenting with it now. This solution would allow for local development and testing but still use lambda after deploy.
On Fri, Sep 23, 2016, 2:07 PM Jonas Helfer notifications@github.com wrote:
@skrigs https://github.com/skrigs That's cool, I'm looking forward to reading that blog post! If it works well, I can definitely see lambda integration becoming an integral part of apollo server.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/apollostack/apollo-server/issues/101#issuecomment-249302632, or mute the thread https://github.com/notifications/unsubscribe-auth/ABq9MvgjFisld4kWRGRylUCleWKMSmiPks5qtD-dgaJpZM4Jo34j .
No I haven't, but the solution I have posted allows the Lambda function to run locally since it uses serverless-webpack.
This may prove relevant to an optimal Apollo Lambda configuration - Lambda just added improved API Gateway support for wildcard endpoints and full request proxying https://aws.amazon.com/about-aws/whats-new/2016/09/aws-lambda-simplifies-amazon-api-gateway-integration/
I experimented with lambda-express. It's not all that great for this purpose. I also tried using serverless-webpack. Sadly, it has several bugs that result in unpredictable behavior.
I ended up getting things working by using a combination of gulp and gulp-webpack to build the app. Then use gulp to call serverless to perform the deploy. That way we get the best of all worlds.
On my side, I have used aws-serverless-express to have a lambda function with express and apollo-server.
Sadly, I have an issue because of chunked transfer encoding
@denneulin I tried aws-serverless-express, suffered the same 'chucked transfer encoding' as you!
Now that we have an easy way to add new packages, it should be possible to create a lambda-specific one if someone has the time.
I will take some time to look into creating a package for lambda
GraphQL server architecturally would require the entire server to be behind one lambda function. At least, the "query server" in your stack.
This raises a flag in my book because lambda is meant for small, isolated, stateless functions that need to be spun up quickly.
I'm assuming that a GraphQL server over time would need to handle quite a bit of resolvers and spinning a lambda function for the entire server for each request seems like it'll have unintended latency costs.
What makes more sense is the functions that GraphQL resolves out to are powered by lambda functions.
However, this is all assumptions. It may be ok to stick an entire server behind a lambda function. It does feel a little obtuse though.
Side note blabbering: if you were designing an HTTP API powered by Lambda you'd create an endpoint in Amazon API Gateway and each endpoint reaches out to a separate Lambda function. This has low cost and latency as each function is small and isolated in purpose. The boot time and overall code size would be small. So in contrast to "an entire GraphQL server behind one lambda function" it raises some concern on viability.
@dfischer Are you saying a lambda function would be too slow for a GraphQL server endpoint? We have done testing and it starts up very quickly. What would you gain by running a full ec2 instance?
I figure I should chime in here.
We are using a modified version of @skrigs apollo lambda implementation (See earlier in the thread for details).
As far as performance goes, I see no difference in running off lambda vs a dedicated instance, and I've implemented both. That being said, there is a lot of code bring executed that would normally only run once. For instance, the schema parser and resolver mapping could be shunted to build time and save those cycles. It's probably not a huge improvement though as all the resources are typically webpacked and already in ram. If that were optimized, there would be little that would merit significant latency.
Keep in mind that aws lambda charges by request and 100ms blocks of run time. The optimizations I mentioned above probably wouldn't take longer than 40ms. The thing to watch out for is the number of requests. A lot of requests will cost you. It's something to consider if you need to defend against ddos for example. It may be better to take the downtime rather then pay for useless requests.
For API gateway, we add a mock for options methods to immediately return the allowed methods with a max age header. This helps us avoid lambda charges for preflight requests.
Ultimately, the biggest latency I've noticed is in db communication and that is the state of things. In my case, the convenance of running a serverless setup is worth any negatives. It really depends on your requirements.
Nice anecdotes, thanks @NeoReyad and @vangorra.
What type of latency are you seeing in the requests with lambda? 100-500ms? The overhead wasn't significant?
It'd be really interesting to build a GraphQL server with Step Functions.
@dfischer Based on the tests and observations I've made with lambda, this is what I have learned. While lambda charges you for how long your handler (graphql request) runs, the lambda service will keep a node instance running for a few minutes with your code in memory ready to go for another request. This hot cache seems to clear after a few minutes of inactivity. It works a lot like fastcgi but with limits. This feature is especially useful for java lambda functions that have a long startup but short runtime.
To test this, I setup a simple graphql function that returns the 1 integer. I have that setup as a lambda-proxy through api gateway. Using postman, I posted a my query {"query": "query{\ntest\n}"} to the api gateway endpoint.
The first run returns in 200-240ms. Each subsequent run is 83ms.
From a cost perspective, lamba offers a special zone where it's cost and service availability is more practical than setting up an elastic beanstalk. Depending on your api's load, it may be most cost effective to use elastic beanstalk with your own ec2 instances. After all, if you had lambda functions running for essentially 24 hours, you'd be paying much much more than if you ran ec2 instances in a load balanced and scaled beanstalk. Do the math and see what will work for you. From my perspective. Lambda allows me to get a stable and scalable api up and running with little to no devops cost. The hope is that once your traffic is high enough to merit an ec2 instance, you also have the resources to migrate to a less expensive solution. Like ec2 and elastic beanstalk.
Since Lambda functions are meant for short lived requests, GraphQL subscriptions (which uses WebSockets) would be a problem. Someone wrote a blog post on a workaround for this, and it looks like an absolute nightmare to set up: https://www.yonomi.co/blog/2019/8/15/graphql-subscriptions-over-aws-api-gateway-web-sockets
There's no mention of subscriptions in Apollo Server's official Lambda documentation page. Are subscriptions supported in this setup? https://www.apollographql.com/docs/apollo-server/deployment/lambda/
Greetings,
I did some cursory searching and couldn't find any mention of running Apollo Server on AWS Lambda - I'm curious if anyone has any experience or guidance for this use-case?
I'm new to the
apollo-server
codebase, but it appears that creating a Lambda integration target should be fairly straightforward. Are there any pitfalls which come to mind to look out for?Thanks!