DEV Community

Oriol Gual for codegram

Posted on • Originally published at on

Ruby & AWS Lambda, ๐Ÿ’– BFF ๐Ÿ’–

Originally published at Codegram's blog

As a Serverless enthusiast at Codegram it was about time I published a new blog post since AWS Lambda has introduced official support for Ruby ๐ŸŽ‰.

You can read more at the official release blog post which also has an example Sinatra app to get started. If you want an in-depth review of the example and release, I recommend this nice review from EquiValent.

I was thrilled to learn that I can finally use Ruby with Lambda, but using Sinatra as an example feels wrong. If you want to build an API with it, you would want to have API Gateway do all the routing and request handling. Adding an extra layer to do the same at the application level is unnecessary and seems like an anti-pattern (I understand itโ€™s used as an example of migrating microservices, but itโ€™s still confusing).

After talking about it with my fellow Codegrammers I decided to build a small proof-of-concept GraphQL API with Ruby and Lambda, using Serverless to simplify the deployment and infrastructure, without Sinatra, Rack or any boilerplate.

The objective was to demonstrate that you can build an API and almost forget that youโ€™re actually dealing with web requests, just focus on the GraphQL schema and the business logic. How does it look like? There are three key elements: serverless.yml exposes our function through an HTTP POST:

service: serverless-ruby-graphql

  name: aws
  runtime: ruby2.5
  region: eu-west-1
  stage: dev

    handler: app.request
      - http:
          path: api
          method: post

  - serverless-hooks-plugin

      - bundle install --deployment
      - rm -fr .bundle
      - rm -fr vendor
      - bundle install
Enter fullscreen mode Exit fullscreen mode

app.rb handles the incoming requests and delegates all the work to GraphQL Ruby:

require 'json'
require_relative "app/graphql/schema"

def request(event:, context:)
  puts "Received Request: #{event}"

  body = Schema.execute(event["body"]).to_json

    statusCode: 200,
    body: body
rescue StandardError => e
  puts e.message
  puts e.backtrace.inspect

    statusCode: 400,
    body: JSON.generate("Bad request, please POST a request body!")

Enter fullscreen mode Exit fullscreen mode

And finally, app/ a folder with all the GraphQL schemas and models:

Although this works OK, keep in mind that it is not production-ready code.

Let's build everything with Lambda

Well, maybe not. Building things with AWS Lambda and Ruby is straightforward, but would I build my next GraphQL API with it? Probably not.

Iโ€™m not entirely sold on using AWS Lambda with user-facing APIs; response times are too unpredictable and quite high (yes, even if you keep your Lambdas warm). Things get [even](( slower if your Lambda needs to access resources inside a VPC (which is necessary if you want to access a database for example).

I really like Lambda, but I think it shines when used to respond to events (such as S3 uploads or Kinesis streams) where you donโ€™t really care about some extra latency but scalability can be an issue.

Iโ€™m eager to try something similar with Knative, Kubeless or OpenWhisk. So far Iโ€™ve only used AWS Lambda, and Iโ€™d like to compare it to other solutions and get a better idea whether it would be a good option to deploy serverless, user-facing APIs.

Top comments (0)