DEV Community

Cover image for Hello Serverless with Jets and Dynamoid
Jalerson Lima
Jalerson Lima

Posted on

Hello Serverless with Jets and Dynamoid

Jets is a Ruby framework which allows us to easily create and deploy serverless applications to AWS. Jets is adopting several concepts and patterns from Rails, which makes much easier the adoption of serverless architectures by Rails developers.

Jets is in early stages of maturity, however, its creator, Tung Nguyen, is making a lot of effort to improve the framework and the community around it is growing.

The application we'll be using as an example is the same previously used in Building AWS Lambdas for Real World using Ruby and Serverless Framework: a simple app which will consume data posted by Github. This sample project is available clicking here.

Like Leeroy Jenkins would say: Alright, time's up! Let's do this!

Prerequisites

Obviously, have Jets installed is necessary. If you don't have, go to your terminal and install it:

$ gem install jets
Enter fullscreen mode Exit fullscreen mode

In order to deploy your app to AWS, you'll need to have your AWS keys set up in ~/.aws/credentials. In case you don't have, please refer to Configuration and Credential files.

Creating our Jets app

Since we're not interested in assets serving, let's create our app using API mode:

$ jets new jetsapp --mode=api
$ cd jetsapp
Enter fullscreen mode Exit fullscreen mode

By default, Jets supports ActiveRecord and DynamoDB via Dynomite. However, I'm interested in something different here: I want to use Dynamoid, which is a stable and mature Ruby ORM for AWS DynamoDB.

That said, let's update our Gemfile to add Dynamoid and remove mysql2.

# gem "mysql2", "~> 0.5.2"
gem 'dynamoid', '~> 3.1.0'
Enter fullscreen mode Exit fullscreen mode

Don't forget to update your dependencies by executing bundle install in your terminal.

Dynamoid requires AWS credentials in order to properly connect to DynamoDB. If we were in Rails, we could easily do it using initializers. Fortunately, initializers are one of the cool stuff adopted by Jets from Rails.

So, we just need to create config/initializers/dynamoid.rb and add the following:

We're configuring the namespace, which is optional (default is dynamoid) and it's a prefix for our DynamoDB tables. We're also setting our AWS access key id, secret key and region. Obviously, we're keeping all these data in our environment variables.

Last but not least, we're creating DynamoDB tables based on the models we have in app/models. Don't worry about the recreation of these tables when you perform a redeploy: Dynamoid takes care of it.

Now, let's update our .env file:

ACCESS_KEY_ID=<your_access_key_id>
SECRET_ACCESS_KEY=<your_secret_access_key>
REGION=<region>
Enter fullscreen mode Exit fullscreen mode

Important: while writing this article, I figured out that are some environment variable names reserved by AWS, for instance, AWS_REGION. So take care to not use them :D

Models

Let's continue updating the app/models/application_item.rb, which is intended to be the parent class of all DynamoDB models. The default ApplicationItem generated by Jets looks like this:

Since we're not using Dynomite, we can remove it and include the Dynamoid::Document.

After that, let's build our GithubEvent model.

As you can see, we're defining the table name, fields names and types (the default is string), as well as some validation rules. Dynamoid automatically creates three fields: id (string), created_at (datetime) and updated_at (datetime).

Dynamoid also allows use to use: default field values, custom field types, associations, validations, callbacks, STI (Single Table Inheritance), record creation, querying and much more.

Controller

Using Jets, we can create a simple lambda function, or we can build our controller and each action will be transformed into an AWS lambda function. Let's use the second approach just because we can!

The github action will be responsible for receiving Github events data. The implementation couldn't be simpler! As you can see, even though we're not implementing a lambda function (which has the event and context arguments), the event variable is available. Btw, params is also available!

Finishing

Let's add the route to our config/routes.rb file:

And finally, execute jets deploy in our terminal to deploy our application. If you don't want to use the default profile to deploy, simply execute AWS_PROFILE=<profile_name> jets deploy.

Final considerations

I really like the idea of Jets framework: to bring concepts and patterns from Rails world to make our lives easier while migrating to serverless. Although the framework is still not mature for critical applications, I will definitely give it a try.

Special thanks to Tung Nguyen for the awesome support!

Looking for a job?

If you're looking for a job and are willing to relocate to Frankfurt (Germany), consider to take a look on the positions available at creditshelf.

Top comments (4)

Collapse
 
philnash profile image
Phil Nash

Thanks for posting this! I've been interested in Jets since I heard about it and I'm going to try something out on it this week. I'll be sure to reference your post about it.

Can I ask why you wanted to use Dynamoid instead of Dynomite?

Collapse
 
jalerson profile image
Jalerson Lima

Hi Phil!

I'm glad you like it! Well, basically because Dynomite looks to be in early stages of development, and Dynamoid also offers more interesting features, like associations, validations, callbacks, etc.

Collapse
 
philnash profile image
Phil Nash

Ah, makes sense. I hadn't heard of either of them before. Thanks!

Collapse
 
mbast100 profile image
Mark Bastawros • Edited

Thanks for this!
I am curious to know if you would be able to run tests using mini-test with this?
i tried but i was getting some errors because rails would try to connect to sqlite3 instead of Dynamodb.