RAILS WITH AWS DynamoDB

Kobe
5 min readFeb 2, 2021

Mysql, the database system is familiar to any programmer today, but with the advancement of technology and new requirements, it seems MySQL with old data storage structures like not enough.

In this article, I would like to introduce to you DYNAMODBa form of NoSQL that has been conquering a lot of programmers in the world.

AWS allows you to download DynamoDB versions from your home page to serve your application development needs in a development environment. So let’s start by installing DynamoDB for use in the Ruby on Rails application

Basically, the article will have:

  • Introduction
  • Install Java
  • Get downloadable DynamoDB
  • Setup DynamoDB via shell
  • Setup Rails project
  • Connect Rails app to local DynamoDB

1. Introduction

To facilitate the application development process AWS allows downloading the full version DynamoDBlocally for installation and usage without having to connect directly to AWS. You can find out the different versions of the service here

In this time I use a demo based on:

  • Ruby 2.4.5
  • Rails 4.2.2
  • Ubuntu 16.04 LTS (Xenial)

2. Install Java

To be able to use DynamoDBit, we need Java to be run, you can install java JRE or JDK:

$ sudo apt-get update
$ sudo apt-get install default-jre

Note: If you get the error ‘E: dpkg was interrupted’ you can fix it by running the command sudo dpkg –configure -a, then continue the steps to install java.

sudo dpkg --configure -a

3. Get downloadable DynamoDB

For more information about the version, DynamoDByou can refer here. Please note that the following URL can be changed, to make sure this URL exists, you can check here.

wget https://s3-us-west-2.amazonaws.com/dynamodb-local/dynamodb_local_latest.tar.gz

Extract the downloaded file with the command:

tar -xvzf dynamodb_local_latest.tar.gz

The download is finished, now we will run DynamoDBthe following command:

java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb

Receiving the following log is successful:

Port:   8000
InMemory: false
DbPath: null
SharedDb: true
shouldDelayTransientStatuses: false
CorsParams: *

Now that you DynamoDBhave run localhost on port 8000, you can run http://localhost:8000/shell/with the following results:

4. Setup DynamoDB via shell

Now we’ve got DynamoDBto run in the local, the next is to try to manipulate the basic commands like create table, Insert,. . .

Note that the above operations can be done on the developing app or you can also use the shell to create data. Access the interface DynamoDBat the path http://localhost:8000/shell/and follow the picture in the picture.

You can see the sample code for the create table function as follows:

var params = {
TableName: 'my_table1',
KeySchema: [
{ // Required HASH type attribute
AttributeName: 'user_id',
KeyType: 'HASH',
}
],
AttributeDefinitions: [
{
AttributeName: 'user_id',
AttributeType: 'N',
}

],
ProvisionedThroughput: {
ReadCapacityUnits: 1,
WriteCapacityUnits: 1,
}
};
dynamodb.createTable(params, function(err, data) {
if (err) ppJson(err); // an error occurred
else ppJson(data); // successful response
});

To insert a record into the DB use the shell as shown below:

var params = {
TableName: 'my_table1',
Item: { // a map of attribute name to AttributeValue
user_id: 11,
age: 19,
phone: '55589xxx'
}
};
docClient.put(params, function(err, data) {
if (err) ppJson(err); // an error occurred
else ppJson(data); // successful response
});

Similar to the item retrieval statement

var params = {
TableName: 'my_table1'
};
dynamodb.scan(params, function(err, data) {
if (err) ppJson(err); // an error occurred
else ppJson(data); // successful response
});

5. Setup Rails project

Use the following command to initiate a basic Rails project ignoring the active record. Also, add gem file to be able to use AWS service

rails new my_app --skip-active-recordgem 'aws-sdk', '~>2'

6. Connect Rails app to local DynamoDB

  1. Store AWS settings

Set up parameters of AWS in secrets.yml

development:
secret_key_base: 42xxx35
dynamodb_access_key_id: <%= ENV["DYNAMODB_ACCESS_KEY_ID"] %>
dynamodb_secret_access_key: <%= ENV["DYNAMODB_SECRET_ACCESS_KEY_ID"] %>
region: <%= ENV["DYNAMODB_REGION"] %>


test:
secret_key_base: 9dfcxxx5e
dynamodb_access_key_id: <%= ENV["DYNAMODB_ACCESS_KEY_ID"] %>
dynamodb_secret_access_key: <%= ENV["DYNAMODB_SECRET_ACCESS_KEY_ID"] %>
region: <%= ENV["DYNAMODB_REGION"] %>

production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
dynamodb_access_key_id: <%= ENV["DYNAMODB_ACCESS_KEY_ID"] %>
dynamodb_secret_access_key: <%= ENV["DYNAMODB_SECRET_ACCESS_KEY_ID"] %>
region: <%= ENV["DYNAMODB_REGION"] %>

Obviously these important parameters you need to put in Ubuntu’s environment variable 2. Setup connection to local DynamoDB

Add the following file config/initializers/aws.rbwith the content

require 'aws'

Add file lib/aws.rbwith content

module Aws

require 'time'

# Initialiaze access to DynamoDB
def self.init

# Set up Client with settings from secrets.yml:
if Rails.env.development?

@client ||= Aws::DynamoDB::Client.new(
endpoint: "http://localhost:8000",
region: "localhost"
)

else

@client ||= Aws::DynamoDB::Client.new(
access_key_id: Rails.application.secrets.dynamodb_access_key_id,
secret_access_key: Rails.application.secrets.dynamodb_secret_access_key,
region: Rails.application.secrets.region
)

end

end

# Save records in DynamoDB table
def self.save_items_to_my_table1(params)


return if !@client

resp = @client.put_item({
item: {
"user_id" => params['user_id'].to_i,
"age" => params['age'],
"created_at" => Time.now.utc.iso8601,
},
return_consumed_capacity: "TOTAL",
table_name: "my_table1",
})

end

# Get all items from DynamoDB my_table1:
def self.get_items

resp = @client.scan({
table_name: "my_table1",
})

# Returns array of items:
return resp.items

end

end

Add settings in config/environment.rb

# Put after Rails.application.initialize!
Aws.init

Use my_table1 in Rails app

The creation controllerand setup routesis similar to any other application.

Below is the demo code of app/controller/my_table1_controller.rb

class MyTable1Controller < ApplicationController


def index
@my_table1_items = Aws.get_items
end

def new
end


def create

user_id = params['user_id']
age = params['age']

aws_params = Hash.new
#aws_params[:mob] = mob
aws_params = {
'user_id' => user_id,
'age' => age
}

if Aws.save_items_to_my_table1(aws_params)
flash[:notice] = "Created!"
else
flash[:error] = "Error!"
end

redirect_to my_table1_index_path

end


end

And here is a new creation form app/views/my_table1/new.html.erb

<%= form_tag(my_table1_index_path) do %>
<input type="text" required="" placeholder="user_id" value="" name="user_id">
<input type="text" required="" placeholder="age" value="" name="age">
<input type="submit" value="submit" name="submit">

Displaying the data after retrieval is also very easy

<h1>My Table 1</h1>

<ul>
<% @my_table1_items.each do |t| %>
<li>
<p>User ID: <%= t['user_id'].to_i %></p>
<p>Age: <%= t['age'] %></p>
<p>Created at: <%= t['created_at'] %></p>
</li>
<% end %>
</ul>

It’s easy, isn’t it? The above is just a demo to help you have a preliminary look DynamoDBto learn more details about it, you can refer to the AWS homepage for a complete and quite detailed guide. Thanks for reading !!!

--

--

Kobe

I’m working at KMS-Technology company. I love code (▀̿Ĺ̯▀̿ ̿) — Full Stack Software Engineer