A good question is: Why would we want a rails Application Programming Interface? Well… you came to the right place. A short quick and simple explanation. An Api serves to maintain, hold and transfer information. Let’s pretend we are a start up and we have a product called tweeter. Tweeter is an application where we can send tweets (thoughts &/or information) on the internet. Now we need a location (databse) to hold our users who sign up and tweet. Our API talks to our database who stores all out information. This is crucial for any application. For now we are involved in the backend (database) and API – (middle backend) of our application.
Continuing with our start up example. We need to set up our rails API. First line of code we need to write is
rails new tweeter –api
we of course called our api “tweeter” but you can give it any name you like
rails new any-name –api
And that is it, our API is up and running. However, we do not have a database set up. For that we need to create a table and rows of information. It is simple, lets look. So our user here will have a username, email, phone number and a password (we will call it password_digest).
rails g scaffold User userName email password_digest phoneNum:integer
rails g scaffold Tweet content user_id:integer
On our column, no need to declare it a string, all info is taken as strings, but phone number which are integers must be declared as integers. Booleans & integers must be declared with their corresponding column.
Next we run rails db:migrate and we have our first table, model, controller, but for now we wont worry about our views, we will take a look at associations our next talk.
Do not forget to bundle our gem ‘bcrypt’ it is essential on our Gemfile. Visit our Gemfile and uncomment or add –
gem bcrypt
Then in our terminal run
bundle install
We are closer now to setting up tweeter.
At this point we need to scaffold a table, migrate that table, create our associations, console into our project and create users and tweet. Sound Simple enough? Lets dive in then!
First lets create out “Tweet” table
rails g scaffold Tweet content user_id:integer
And we get
class CreateTweets < ActiveRecord::Migration[6.0]
def change
create_table :tweets do |t|
t.string :content
t.integer :user_id
t.timestamps
end
end
end
So now we have a user table and Tweet table and we need to migrate them.
rails db:migrate
At this point our controller and model have been set up.
class Tweet < ApplicationRecord
end
&
class TweetsController < ApplicationController
before_action :set_tweet, only: [:show, :update, :destroy]
# GET /tweets
def index
@tweets = Tweet.all
render json: @tweets
end
# GET /tweets/1
def show
render json: @tweet
end
# POST /tweets
def create
@tweet = Tweet.new(tweet_params)
if @tweet.save
render json: @tweet, status: :created, location: @tweet
else
render json: @tweet.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /tweets/1
def update
if @tweet.update(tweet_params)
render json: @tweet
else
render json: @tweet.errors, status: :unprocessable_entity
end
end
# DELETE /tweets/1
def destroy
@tweet.destroy
end
private
# Use callbacks to share common setup or constraints between actions.
def set_tweet
@tweet = Tweet.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def tweet_params
params.require(:tweet).permit(:content, :user_id)
end
end
This outcome applies to our User table too. However, our models need an association, how would our table look now? Both User and Tweet
class User < ApplicationRecord
has_many :tweets
end
&
class Tweet < ApplicationRecord
belongs_to :user
has_secure_password
end
What happened here? Well we are bringing in extra methods that can be called upon when we need to derive associated information. Our ‘‘has_secure_password” helps to mantain our password hidden when displaying information, it needs ‘gem bcrypt’ to function. I do need some extra users in the database however, so I’ll dig into the console and add them manually.
rails c
then
User.create(username: "rocky", phoneNum: 2021234567, email: "rocky@email.com", password_digest: "rocky")
& a Tweet
Tweet.create(content: "First tweet!", user_id: 1)
The user id column is so important, that is where we put the id of the user who creates the Tweet. Now when we run
Tweet.all
or
User.all
in our console and we see we have populated information. To see our data display as json data, we simply go to our localhost and use the routes. Run
rails s
in your terminal and In this case we will go to
localhost:3000/users
&
localhost:3000/tweets
in our browser, (yes it has to be plural or according to your routes if changed). All our information we inserted manually should be there waiting for us.
That was not so bad! Next, we will utilize active model serializers to display information that is associated with one another
To setup our Active model serializers we need a few steps. It will be so quick; it will surprise you. Before we start let us look at the data that is presented to us when we initialize our localhost and hit our routes from our backend
[
{
id: 1,
username: "rocky",
phoneNum: 2021234567,
email: "rocky@email.com",
password_digest: "rocky"
}
]
Our password is being shared; we do not want that. So, lets fix it. First, we must access our gem files and add our gem.
gem 'active_models_serializers'
Then install with
bundle install
Once we have set our gem up, we need to create the serializer objects based on the models we have created.
rails g serializer User
rails g serializer Tweet
Great. Now we have our serializers:
class UserSerializer < ActiveModel::Serializer
attributes :id
end
Oh no, we have only one attribute on our serializers.
[
{
id: 1
}
]
Here is where we add or remove our information. Naturally with our routes, our information is being sent through our controllers. But with our serializer we control the data and what is being displayed.
class UserSerializer < ActiveModel::Serializer
attributes :id,
:username,
:phoneNum,
:email
end
Fantastic, we now are sending the specific information we want to share and display Our data now looks like this.
[
{
id: 1,
username: "rocky",
phoneNum: 2021234567,
email: "rocky@email.com",
}
]
A cool trick is to associate data through our serializers, it’s just like creating associations between our models. It looks something like this.
[
{
id: 1,
username: "rocky",
phoneNum: 2021234567,
email: "rocky@email.com",
tweets: [
{
id: 1,
content: "My first Tweet",
user_id: 1
}
]
}
]
How cool is that? We now have finished building Tweeter’s Backend, what an accomplishment!
One last thing, on your Config/Application.rb file you must have your file like this
class Application < Rails::Application
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*', headers: :any, methods: [:get, :post, :delete, :patch, :options]
end
end
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 6.0
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.
# Only loads a smaller set of middleware suitable for API only apps.
# Middleware like session, flash, cookies can be added back manually.
# Skip views, helpers and assets when generating a new resource.
config.api_only = true
end
and add the rack CORS gem.
gem 'rack-cors'
along with pry if you so desire
gem 'pry'
then we bundle install.
Now you are ready to do some Asynchronous calls to your --API
Thoughts? let me know!
Top comments (0)