Skip to content

Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Rails-API-React-Tutorial 💻 Open Source Love

Hey! This is a super-easy to follow Rails/React API tutorial that is fully in depth from start to finish. This guide shows you how to install Ruby and Rails 5 in a Virtual Box, React JS via create-react-app and connecting the frontend and backend.

Table of Contents

Downloading Virtual Box

  • Why Virtual Box? What is it? We'll be using Ubuntu to work with our rails applications so it'll be more organized for us to be working in a virtual enviorment! You can always destroy the enviorment and reconfigure whenever you want.
  1. Download VirtualBox 5.2.22 for Mac OSX here, or Windows here
  2. Run the installer.
  3. Download Vagrant for Mac OSX here, or Windows here
  4. Let's create our first enviorment. You can run the script below to keep your rails projects on your Desktop.
cd /Desktop && mkdir rails && cd rails && vagrant init
  1. Download the OS to VirtualBox
vagrant box add ubuntu/trusty64
  1. Double check and make sure our new box is there
vagrant box list
  1. Add this script to the Vagrant File
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
end
  1. Start the vagrant server
vagrant up && vagrant ssh
  1. Direct yourself to the vagrant directory
cd /vagrant
  1. Add our Bootstrap File
mkdir new_project && cd new_project && touch bootstrap.sh
  1. Copy this script to configure our virtual enviorment
#!/usr/bin/env bash
# upgrade and update the system
echo upgrading and updating the system
sudo apt-get update
sudo apt-get -y upgrade
# install node.js for js runtime when using Rails
echo installing nodejs for ExecJS runtime and git
sudo apt-get install -y nodejs
sudo apt-get install -y git
# install RVM
echo installing RVM
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash -s stable
source /home/vagrant/.rvm/scripts/rvm
rvm requirements
# install Ruby and make 2.3.1 the default
echo installing ruby
rvm install 2.3.1
rvm use 2.3.1 --default
# install Bundler and Rails
echo installing bundler and rails
gem install bundler --no-ri --no-rdoc
gem install rails -v 4.2.7 --no-ri --no-rdoc
# install postgres and its dependencies
echo installing psql and its dependencies
sudo apt-get install -y postgresql postgresql-contrib libpq-dev
  1. Re-edit the vagrant file for our newest editions + new bootstrap file
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network "forwarded_port", guest: 3000, host: 3000, host_ip: "127.0.0.1"
config.vm.provision :shell, path: "bootstrap.sh", privileged: false
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--memory", "2048"]
vb.customize ["modifyvm", :id, "--cpus", "2"]
end
end
  1. Open a new tab in your terminal and lets test the vagrant configs
vagrant halt && vagrant up --provision
  1. Last step. whew...! Once your vagrant server is on (vagrant up and vagrant ssh!), check that Ruby and Rails was installed!
ruby -v

Downloading create-react-app

First we need Node Packet Manager if you dont already. You can download it here. Run the installer and save settings so npm is saved globally.

Let's begin!

  1. run npm install -g create-react-app and let the files download to your drive.

1a. If you are running problems with the ERR! message, try using sudo to run privileges as administrator.

  1. Let's create a test app to see if everything is running smoothly. type create-react-app my-cool-app in the command line and see if everything installs. my-cool-app will be the name of your react project.

  2. Run npm start and type Y in case there are some conflicting port configs in your local host. You should see the bottom image in your browser if everything was installed correctly!

Image and video hosting by TinyPic

Rails API 💎

Now that have our virtual enviorment ready, we can create our first ever Rails API. The new rails api command scaffolds everything we need to get up and ready for our project. Let's start our vagrant server and ssh into our project folder.

  1. Run the following: rails new my-first-api --api -T

What's going on here? The --api command tells rails that we want an API structure application instead of a standard rails structure. The -T command also tells rails that we don't want Minitest as our testing suite. You'll most likely be used to Rspec so we'll talk about that later in the guide.

  1. Enable Cross-Origin Resource Sharing (CORS) in your gem and config directory. Locate your gemfile and uncomment the following
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possiblegem'rack-cors'

Do not forget to bundle install !

Now in your config/initializers directory, you should now see a cors.rb file. Add the following to

# config/initializers/cors.rbclassApplication < Rails::Applicationconfig.middleware.insert_before0,"Rack::Cors"doallowdoorigins'*'resource'*',:headers=>:any,:methods=>[:get,:post,:patch,:options]endendend

Since this tutorial is mainly for testing and toy projects, we are allowing ALL methods from another domain. You should tailor the header and methods to your liking.

Rails API Versioning

Versioning is the process of seperating and creating new features/data/endpoints for your API. Since this is our first API, let's make our test-api v1.

  1. Run the following in your terminal
mkdir mkdir app/controllers/api && mkdir app/controllers/api/v1

If everything looks right you should see your directory identical as below.

Image and video hosting by TinyPic

Now that our versioning is complete, let's test out a model and controller to work with our new url of localhost:3000/api/v1.

  1. Let's scaffold a test model/controller and call it movies
railsgscaffoldMoviesname:stringrating:integerrailsdb:migrate

The Rails engine creates your controller in the default /controllers directory but we need to move our new controller into the api/v1 directory.

  1. You can either move it manually or the following:
mv app/controllers/movies_controller.rb app/controllers/api/v1
  1. Update the Movies Controller

Our newly generated controller does not properly inherit from the namespace api/v1 (We will update the routes later in the tutorial) so let's change our controller class from

classMoviesController < ApplicationController

TO

classApi::V1::MoviesController < ApplicationController
  1. Update the Routes Locate to your config folder and open your routes.rb file.
Rails.application.routes.drawdoresources:moviesend

If we go to localhost:3000/movies we will not call the controller. We must update our Routes to:

Rails.application.routes.drawdonamespace:apidonamespace:v1doresources:moviesendendend

which allows us to call the json data from localhost:3000/api/v1/movies

  1. Let's seed our sqlite database with some classic movies so we can practice getting data with GET requests to the API.

Copy and paste the following data to your db/seeds.rb file.

Movie.create(name: "The Nightmare Before Christmas",rating: 5)Movie.create(name: "Titanic",rating: 5)Movie.create(name: "Venom",rating: 4)Movie.create(name: "A Quiet Place",rating: 5)Movie.create(name: "Nobody's Fool",rating: 2)Movie.create(name: "Suspiria",rating: 4)Movie.create(name: "Hereditary",rating: 4)Movie.create(name: "Office Space",rating: 5)Movie.create(name: "Elf",rating: 4)Movie.create(name: "Dawn of the Planet of the Apes",rating: 3)Movie.create(name: "Secret life of Pets",rating: 4)Movie.create(name: "Overlord",rating: 3)Movie.create(name: "Wonder Woman",rating: 5)Movie.create(name: "Bohemian Rhapsody",rating: 4)Movie.create(name: "Ocean's 8",rating: 5)

Seed the DB using rails db:seed && rails db:migrate

  1. Test the API using a GET request.

Start your Rails server rails s and navigate to localhost:3000/api/v1/movies and if it is successful you should see the following JSON output:

(Optional) I'm using a pretty JSON viewer for chrome which you can download here.Image and video hosting by TinyPic

Congrats! You have successfully created a Rails API and completed your first GET request!

Downloading React into our Project

React is a component based front end framework that makes it easy to make frontend calls to our Rails API. Let's make this organized as possible and add our react directory inside our rails app.

  1. Open your terminal and create a new project inside your API.
create-react-app client

Image and video hosting by TinyPic
  1. Download Boostrap into the react directory:
npm install --save reactstrap bootstrap@4

Then open your index.js file inside the /src directory and add the following import line:

importReactfrom"react";importReactDOMfrom"react-dom";import"./index.css";importAppfrom"./App";import*asserviceWorkerfrom"./serviceWorker";// Import goes below for Bootstrapimport"bootstrap/dist/css/bootstrap.css";
  1. Let's proxy our client so we know where to get the requests from!

Open package.json from our react folder and add the following json code to your package.

"proxy": "http://127.0.0.1:3000",

Heres mine as an example!

{"name": "client","version": "0.1.0","private": true,"proxy": "http://127.0.0.1:3000","dependencies": {"bootstrap": "^4.1.3","react": "^16.6.3","react-dom": "^16.6.3","react-scripts": "2.1.1","reactstrap": "^6.5.0"},
  1. We'll make a default Component directory inside the /src folder and create our first component.
cd client/src && mkdir components && cd components && touch Button.js
  1. Open your Button.js file and lets create a sample button to activate our call function to the API.
importReact,{Component}from"react";classButtonextendsComponent{render(){return(<div><divclass="card container mt-3"><divclass="card-body"><divclass="row"><center><buttonclass="btn btn-primary">Test Call!</button></center></div></div></div></div>);}}exportdefaultButton;
  1. Start your server npm start and check if your bootstrap import works as well as the test button! If all is displaying then we are almost done. We are sooooo close!

We want our button to actually call the API now so lets create the function with the appropriate call. We want to add an onclick event to the button html like so:

<buttonclass="btn btn-primary"onClick={this.callApi}>
Test Call!
</button>

and our custom function PLUS the initial state set to null

state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};

After copying and pasting both snippets inside the Button.js file, we fetch from the url http://localhost:3000/api/v1/movies in a json format and once we return a true response we will set the response to the data variable and console log the results into the browser.

This should be the complete Button.js file below!

importReact,{Component}from"react";classButtonextendsComponent{state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};render(){return(<div><divclassName="card container mt-3"><divclassName="card-body"><divclassName="row"><center><buttonclassName="btn btn-primary"onClick={this.callApi}>
Test Call!
</button><br/></center><br/><br/><br/><br/><br/><pclassName="m-5">{this.state.results.map(obj=><li>{obj.name}</li>)}</p></div></div></div></div>);}}exportdefaultButton;
  1. Finally, let's open our App.js file in the /src directory to add our new Button Component to the App itself. Check below to see the example. Don't forget that we need to enclose the <Button /> in two <div></div> tags!
importReact,{Component}from'react';importlogofrom'./logo.svg';import'./App.css';importButtonfrom'./components/Button';classAppextendsComponent{render(){return(<div><Button/></div>);}}exportdefaultApp;

This should be everything we need to setup the API. Simply click our test api call button and see the magic work!

Congratulations! Our Rails API and React Client is done! If you enjoyed this API tutorial please give it a star and share it with your friends!

Rails Serializers

What are Serializers? Well Rails API's returns JSON data in full, so serializers allows us to cherry pick the exact data we want in a much organized fashion. Instead of getting every column from the returned data, we can grab which ever we allow to pass through.

Normal ModelSerializer Model
id, name, rating, director, score, actors_id, created_at, updated_atid, name, rating

We are able to tell the Rails API what to fetch rather than the frontend; making it much more simple and faster to scaffold your next project.

  1. Installation

Open your gemfile and add the serializer gem into your project. Don't forget to bundle install !

# Serializergem'active_model_serializers'

We want to create a clone of any current model we have so when we make requests in the backend, the request will read the serializer file first, then it will find the rails model/controller to finisht the request. We have a model called Movie so we'll duplicate that by running:

rails g serializer movie

You can see that a new directory was made in the app/ directory and we now have app/serializers/movie_serializer file in our project.

Let's open that file and see what we have:

classMovieSerializer < ActiveModel::Serializerattributes:idend

We have our Movie Class inheriting from the serializer class on the first line, and the returned attribute on the second. So far the default returned attribute is just an ID. Let's test this now!

1a. Turn on your rails server and go to the url localhost:3000/api/v1/movies

You should see that only the id attribute is being returned from the database.

{
id: 1
},
{
id: 2
},
{
id: 3
}

You can add any attribute to your liking to the serializer file for your next big project. But that's the end of the serializer section!

About

📱A Rails 5 API backend React JS Frontend Guide 💞

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - wkhatch/Rails-API-React-Tutorial: 📱A Rails 5 API backend React JS Frontend Guide 💞 · GitHub
Skip to content

Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Rails-API-React-Tutorial 💻 Open Source Love

Hey! This is a super-easy to follow Rails/React API tutorial that is fully in depth from start to finish. This guide shows you how to install Ruby and Rails 5 in a Virtual Box, React JS via create-react-app and connecting the frontend and backend.

Table of Contents

Downloading Virtual Box

  • Why Virtual Box? What is it? We'll be using Ubuntu to work with our rails applications so it'll be more organized for us to be working in a virtual enviorment! You can always destroy the enviorment and reconfigure whenever you want.
  1. Download VirtualBox 5.2.22 for Mac OSX here, or Windows here
  2. Run the installer.
  3. Download Vagrant for Mac OSX here, or Windows here
  4. Let's create our first enviorment. You can run the script below to keep your rails projects on your Desktop.
cd /Desktop && mkdir rails && cd rails && vagrant init
  1. Download the OS to VirtualBox
vagrant box add ubuntu/trusty64
  1. Double check and make sure our new box is there
vagrant box list
  1. Add this script to the Vagrant File
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
end
  1. Start the vagrant server
vagrant up && vagrant ssh
  1. Direct yourself to the vagrant directory
cd /vagrant
  1. Add our Bootstrap File
mkdir new_project && cd new_project && touch bootstrap.sh
  1. Copy this script to configure our virtual enviorment
#!/usr/bin/env bash
# upgrade and update the system
echo upgrading and updating the system
sudo apt-get update
sudo apt-get -y upgrade
# install node.js for js runtime when using Rails
echo installing nodejs for ExecJS runtime and git
sudo apt-get install -y nodejs
sudo apt-get install -y git
# install RVM
echo installing RVM
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash -s stable
source /home/vagrant/.rvm/scripts/rvm
rvm requirements
# install Ruby and make 2.3.1 the default
echo installing ruby
rvm install 2.3.1
rvm use 2.3.1 --default
# install Bundler and Rails
echo installing bundler and rails
gem install bundler --no-ri --no-rdoc
gem install rails -v 4.2.7 --no-ri --no-rdoc
# install postgres and its dependencies
echo installing psql and its dependencies
sudo apt-get install -y postgresql postgresql-contrib libpq-dev
  1. Re-edit the vagrant file for our newest editions + new bootstrap file
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network "forwarded_port", guest: 3000, host: 3000, host_ip: "127.0.0.1"
config.vm.provision :shell, path: "bootstrap.sh", privileged: false
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--memory", "2048"]
vb.customize ["modifyvm", :id, "--cpus", "2"]
end
end
  1. Open a new tab in your terminal and lets test the vagrant configs
vagrant halt && vagrant up --provision
  1. Last step. whew...! Once your vagrant server is on (vagrant up and vagrant ssh!), check that Ruby and Rails was installed!
ruby -v

Downloading create-react-app

First we need Node Packet Manager if you dont already. You can download it here. Run the installer and save settings so npm is saved globally.

Let's begin!

  1. run npm install -g create-react-app and let the files download to your drive.

1a. If you are running problems with the ERR! message, try using sudo to run privileges as administrator.

  1. Let's create a test app to see if everything is running smoothly. type create-react-app my-cool-app in the command line and see if everything installs. my-cool-app will be the name of your react project.

  2. Run npm start and type Y in case there are some conflicting port configs in your local host. You should see the bottom image in your browser if everything was installed correctly!

Image and video hosting by TinyPic

Rails API 💎

Now that have our virtual enviorment ready, we can create our first ever Rails API. The new rails api command scaffolds everything we need to get up and ready for our project. Let's start our vagrant server and ssh into our project folder.

  1. Run the following: rails new my-first-api --api -T

What's going on here? The --api command tells rails that we want an API structure application instead of a standard rails structure. The -T command also tells rails that we don't want Minitest as our testing suite. You'll most likely be used to Rspec so we'll talk about that later in the guide.

  1. Enable Cross-Origin Resource Sharing (CORS) in your gem and config directory. Locate your gemfile and uncomment the following
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possiblegem'rack-cors'

Do not forget to bundle install !

Now in your config/initializers directory, you should now see a cors.rb file. Add the following to

# config/initializers/cors.rbclassApplication < Rails::Applicationconfig.middleware.insert_before0,"Rack::Cors"doallowdoorigins'*'resource'*',:headers=>:any,:methods=>[:get,:post,:patch,:options]endendend

Since this tutorial is mainly for testing and toy projects, we are allowing ALL methods from another domain. You should tailor the header and methods to your liking.

Rails API Versioning

Versioning is the process of seperating and creating new features/data/endpoints for your API. Since this is our first API, let's make our test-api v1.

  1. Run the following in your terminal
mkdir mkdir app/controllers/api && mkdir app/controllers/api/v1

If everything looks right you should see your directory identical as below.

Image and video hosting by TinyPic

Now that our versioning is complete, let's test out a model and controller to work with our new url of localhost:3000/api/v1.

  1. Let's scaffold a test model/controller and call it movies
railsgscaffoldMoviesname:stringrating:integerrailsdb:migrate

The Rails engine creates your controller in the default /controllers directory but we need to move our new controller into the api/v1 directory.

  1. You can either move it manually or the following:
mv app/controllers/movies_controller.rb app/controllers/api/v1
  1. Update the Movies Controller

Our newly generated controller does not properly inherit from the namespace api/v1 (We will update the routes later in the tutorial) so let's change our controller class from

classMoviesController < ApplicationController

TO

classApi::V1::MoviesController < ApplicationController
  1. Update the Routes Locate to your config folder and open your routes.rb file.
Rails.application.routes.drawdoresources:moviesend

If we go to localhost:3000/movies we will not call the controller. We must update our Routes to:

Rails.application.routes.drawdonamespace:apidonamespace:v1doresources:moviesendendend

which allows us to call the json data from localhost:3000/api/v1/movies

  1. Let's seed our sqlite database with some classic movies so we can practice getting data with GET requests to the API.

Copy and paste the following data to your db/seeds.rb file.

Movie.create(name: "The Nightmare Before Christmas",rating: 5)Movie.create(name: "Titanic",rating: 5)Movie.create(name: "Venom",rating: 4)Movie.create(name: "A Quiet Place",rating: 5)Movie.create(name: "Nobody's Fool",rating: 2)Movie.create(name: "Suspiria",rating: 4)Movie.create(name: "Hereditary",rating: 4)Movie.create(name: "Office Space",rating: 5)Movie.create(name: "Elf",rating: 4)Movie.create(name: "Dawn of the Planet of the Apes",rating: 3)Movie.create(name: "Secret life of Pets",rating: 4)Movie.create(name: "Overlord",rating: 3)Movie.create(name: "Wonder Woman",rating: 5)Movie.create(name: "Bohemian Rhapsody",rating: 4)Movie.create(name: "Ocean's 8",rating: 5)

Seed the DB using rails db:seed && rails db:migrate

  1. Test the API using a GET request.

Start your Rails server rails s and navigate to localhost:3000/api/v1/movies and if it is successful you should see the following JSON output:

(Optional) I'm using a pretty JSON viewer for chrome which you can download here.Image and video hosting by TinyPic

Congrats! You have successfully created a Rails API and completed your first GET request!

Downloading React into our Project

React is a component based front end framework that makes it easy to make frontend calls to our Rails API. Let's make this organized as possible and add our react directory inside our rails app.

  1. Open your terminal and create a new project inside your API.
create-react-app client

Image and video hosting by TinyPic
  1. Download Boostrap into the react directory:
npm install --save reactstrap bootstrap@4

Then open your index.js file inside the /src directory and add the following import line:

importReactfrom"react";importReactDOMfrom"react-dom";import"./index.css";importAppfrom"./App";import*asserviceWorkerfrom"./serviceWorker";// Import goes below for Bootstrapimport"bootstrap/dist/css/bootstrap.css";
  1. Let's proxy our client so we know where to get the requests from!

Open package.json from our react folder and add the following json code to your package.

"proxy": "http://127.0.0.1:3000",

Heres mine as an example!

{"name": "client","version": "0.1.0","private": true,"proxy": "http://127.0.0.1:3000","dependencies": {"bootstrap": "^4.1.3","react": "^16.6.3","react-dom": "^16.6.3","react-scripts": "2.1.1","reactstrap": "^6.5.0"},
  1. We'll make a default Component directory inside the /src folder and create our first component.
cd client/src && mkdir components && cd components && touch Button.js
  1. Open your Button.js file and lets create a sample button to activate our call function to the API.
importReact,{Component}from"react";classButtonextendsComponent{render(){return(<div><divclass="card container mt-3"><divclass="card-body"><divclass="row"><center><buttonclass="btn btn-primary">Test Call!</button></center></div></div></div></div>);}}exportdefaultButton;
  1. Start your server npm start and check if your bootstrap import works as well as the test button! If all is displaying then we are almost done. We are sooooo close!

We want our button to actually call the API now so lets create the function with the appropriate call. We want to add an onclick event to the button html like so:

<buttonclass="btn btn-primary"onClick={this.callApi}>
Test Call!
</button>

and our custom function PLUS the initial state set to null

state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};

After copying and pasting both snippets inside the Button.js file, we fetch from the url http://localhost:3000/api/v1/movies in a json format and once we return a true response we will set the response to the data variable and console log the results into the browser.

This should be the complete Button.js file below!

importReact,{Component}from"react";classButtonextendsComponent{state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};render(){return(<div><divclassName="card container mt-3"><divclassName="card-body"><divclassName="row"><center><buttonclassName="btn btn-primary"onClick={this.callApi}>
Test Call!
</button><br/></center><br/><br/><br/><br/><br/><pclassName="m-5">{this.state.results.map(obj=><li>{obj.name}</li>)}</p></div></div></div></div>);}}exportdefaultButton;
  1. Finally, let's open our App.js file in the /src directory to add our new Button Component to the App itself. Check below to see the example. Don't forget that we need to enclose the <Button /> in two <div></div> tags!
importReact,{Component}from'react';importlogofrom'./logo.svg';import'./App.css';importButtonfrom'./components/Button';classAppextendsComponent{render(){return(<div><Button/></div>);}}exportdefaultApp;

This should be everything we need to setup the API. Simply click our test api call button and see the magic work!

Congratulations! Our Rails API and React Client is done! If you enjoyed this API tutorial please give it a star and share it with your friends!

Rails Serializers

What are Serializers? Well Rails API's returns JSON data in full, so serializers allows us to cherry pick the exact data we want in a much organized fashion. Instead of getting every column from the returned data, we can grab which ever we allow to pass through.

Normal ModelSerializer Model
id, name, rating, director, score, actors_id, created_at, updated_atid, name, rating

We are able to tell the Rails API what to fetch rather than the frontend; making it much more simple and faster to scaffold your next project.

  1. Installation

Open your gemfile and add the serializer gem into your project. Don't forget to bundle install !

# Serializergem'active_model_serializers'

We want to create a clone of any current model we have so when we make requests in the backend, the request will read the serializer file first, then it will find the rails model/controller to finisht the request. We have a model called Movie so we'll duplicate that by running:

rails g serializer movie

You can see that a new directory was made in the app/ directory and we now have app/serializers/movie_serializer file in our project.

Let's open that file and see what we have:

classMovieSerializer < ActiveModel::Serializerattributes:idend

We have our Movie Class inheriting from the serializer class on the first line, and the returned attribute on the second. So far the default returned attribute is just an ID. Let's test this now!

1a. Turn on your rails server and go to the url localhost:3000/api/v1/movies

You should see that only the id attribute is being returned from the database.

{
id: 1
},
{
id: 2
},
{
id: 3
}

You can add any attribute to your liking to the serializer file for your next big project. But that's the end of the serializer section!

About

📱A Rails 5 API backend React JS Frontend Guide 💞

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - wkhatch/Rails-API-React-Tutorial: 📱A Rails 5 API backend React JS Frontend Guide 💞 · GitHub
Skip to content

Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Rails-API-React-Tutorial 💻 Open Source Love

Hey! This is a super-easy to follow Rails/React API tutorial that is fully in depth from start to finish. This guide shows you how to install Ruby and Rails 5 in a Virtual Box, React JS via create-react-app and connecting the frontend and backend.

Table of Contents

Downloading Virtual Box

  • Why Virtual Box? What is it? We'll be using Ubuntu to work with our rails applications so it'll be more organized for us to be working in a virtual enviorment! You can always destroy the enviorment and reconfigure whenever you want.
  1. Download VirtualBox 5.2.22 for Mac OSX here, or Windows here
  2. Run the installer.
  3. Download Vagrant for Mac OSX here, or Windows here
  4. Let's create our first enviorment. You can run the script below to keep your rails projects on your Desktop.
cd /Desktop && mkdir rails && cd rails && vagrant init
  1. Download the OS to VirtualBox
vagrant box add ubuntu/trusty64
  1. Double check and make sure our new box is there
vagrant box list
  1. Add this script to the Vagrant File
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
end
  1. Start the vagrant server
vagrant up && vagrant ssh
  1. Direct yourself to the vagrant directory
cd /vagrant
  1. Add our Bootstrap File
mkdir new_project && cd new_project && touch bootstrap.sh
  1. Copy this script to configure our virtual enviorment
#!/usr/bin/env bash
# upgrade and update the system
echo upgrading and updating the system
sudo apt-get update
sudo apt-get -y upgrade
# install node.js for js runtime when using Rails
echo installing nodejs for ExecJS runtime and git
sudo apt-get install -y nodejs
sudo apt-get install -y git
# install RVM
echo installing RVM
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash -s stable
source /home/vagrant/.rvm/scripts/rvm
rvm requirements
# install Ruby and make 2.3.1 the default
echo installing ruby
rvm install 2.3.1
rvm use 2.3.1 --default
# install Bundler and Rails
echo installing bundler and rails
gem install bundler --no-ri --no-rdoc
gem install rails -v 4.2.7 --no-ri --no-rdoc
# install postgres and its dependencies
echo installing psql and its dependencies
sudo apt-get install -y postgresql postgresql-contrib libpq-dev
  1. Re-edit the vagrant file for our newest editions + new bootstrap file
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network "forwarded_port", guest: 3000, host: 3000, host_ip: "127.0.0.1"
config.vm.provision :shell, path: "bootstrap.sh", privileged: false
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--memory", "2048"]
vb.customize ["modifyvm", :id, "--cpus", "2"]
end
end
  1. Open a new tab in your terminal and lets test the vagrant configs
vagrant halt && vagrant up --provision
  1. Last step. whew...! Once your vagrant server is on (vagrant up and vagrant ssh!), check that Ruby and Rails was installed!
ruby -v

Downloading create-react-app

First we need Node Packet Manager if you dont already. You can download it here. Run the installer and save settings so npm is saved globally.

Let's begin!

  1. run npm install -g create-react-app and let the files download to your drive.

1a. If you are running problems with the ERR! message, try using sudo to run privileges as administrator.

  1. Let's create a test app to see if everything is running smoothly. type create-react-app my-cool-app in the command line and see if everything installs. my-cool-app will be the name of your react project.

  2. Run npm start and type Y in case there are some conflicting port configs in your local host. You should see the bottom image in your browser if everything was installed correctly!

Image and video hosting by TinyPic

Rails API 💎

Now that have our virtual enviorment ready, we can create our first ever Rails API. The new rails api command scaffolds everything we need to get up and ready for our project. Let's start our vagrant server and ssh into our project folder.

  1. Run the following: rails new my-first-api --api -T

What's going on here? The --api command tells rails that we want an API structure application instead of a standard rails structure. The -T command also tells rails that we don't want Minitest as our testing suite. You'll most likely be used to Rspec so we'll talk about that later in the guide.

  1. Enable Cross-Origin Resource Sharing (CORS) in your gem and config directory. Locate your gemfile and uncomment the following
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possiblegem'rack-cors'

Do not forget to bundle install !

Now in your config/initializers directory, you should now see a cors.rb file. Add the following to

# config/initializers/cors.rbclassApplication < Rails::Applicationconfig.middleware.insert_before0,"Rack::Cors"doallowdoorigins'*'resource'*',:headers=>:any,:methods=>[:get,:post,:patch,:options]endendend

Since this tutorial is mainly for testing and toy projects, we are allowing ALL methods from another domain. You should tailor the header and methods to your liking.

Rails API Versioning

Versioning is the process of seperating and creating new features/data/endpoints for your API. Since this is our first API, let's make our test-api v1.

  1. Run the following in your terminal
mkdir mkdir app/controllers/api && mkdir app/controllers/api/v1

If everything looks right you should see your directory identical as below.

Image and video hosting by TinyPic

Now that our versioning is complete, let's test out a model and controller to work with our new url of localhost:3000/api/v1.

  1. Let's scaffold a test model/controller and call it movies
railsgscaffoldMoviesname:stringrating:integerrailsdb:migrate

The Rails engine creates your controller in the default /controllers directory but we need to move our new controller into the api/v1 directory.

  1. You can either move it manually or the following:
mv app/controllers/movies_controller.rb app/controllers/api/v1
  1. Update the Movies Controller

Our newly generated controller does not properly inherit from the namespace api/v1 (We will update the routes later in the tutorial) so let's change our controller class from

classMoviesController < ApplicationController

TO

classApi::V1::MoviesController < ApplicationController
  1. Update the Routes Locate to your config folder and open your routes.rb file.
Rails.application.routes.drawdoresources:moviesend

If we go to localhost:3000/movies we will not call the controller. We must update our Routes to:

Rails.application.routes.drawdonamespace:apidonamespace:v1doresources:moviesendendend

which allows us to call the json data from localhost:3000/api/v1/movies

  1. Let's seed our sqlite database with some classic movies so we can practice getting data with GET requests to the API.

Copy and paste the following data to your db/seeds.rb file.

Movie.create(name: "The Nightmare Before Christmas",rating: 5)Movie.create(name: "Titanic",rating: 5)Movie.create(name: "Venom",rating: 4)Movie.create(name: "A Quiet Place",rating: 5)Movie.create(name: "Nobody's Fool",rating: 2)Movie.create(name: "Suspiria",rating: 4)Movie.create(name: "Hereditary",rating: 4)Movie.create(name: "Office Space",rating: 5)Movie.create(name: "Elf",rating: 4)Movie.create(name: "Dawn of the Planet of the Apes",rating: 3)Movie.create(name: "Secret life of Pets",rating: 4)Movie.create(name: "Overlord",rating: 3)Movie.create(name: "Wonder Woman",rating: 5)Movie.create(name: "Bohemian Rhapsody",rating: 4)Movie.create(name: "Ocean's 8",rating: 5)

Seed the DB using rails db:seed && rails db:migrate

  1. Test the API using a GET request.

Start your Rails server rails s and navigate to localhost:3000/api/v1/movies and if it is successful you should see the following JSON output:

(Optional) I'm using a pretty JSON viewer for chrome which you can download here.Image and video hosting by TinyPic

Congrats! You have successfully created a Rails API and completed your first GET request!

Downloading React into our Project

React is a component based front end framework that makes it easy to make frontend calls to our Rails API. Let's make this organized as possible and add our react directory inside our rails app.

  1. Open your terminal and create a new project inside your API.
create-react-app client

Image and video hosting by TinyPic
  1. Download Boostrap into the react directory:
npm install --save reactstrap bootstrap@4

Then open your index.js file inside the /src directory and add the following import line:

importReactfrom"react";importReactDOMfrom"react-dom";import"./index.css";importAppfrom"./App";import*asserviceWorkerfrom"./serviceWorker";// Import goes below for Bootstrapimport"bootstrap/dist/css/bootstrap.css";
  1. Let's proxy our client so we know where to get the requests from!

Open package.json from our react folder and add the following json code to your package.

"proxy": "http://127.0.0.1:3000",

Heres mine as an example!

{"name": "client","version": "0.1.0","private": true,"proxy": "http://127.0.0.1:3000","dependencies": {"bootstrap": "^4.1.3","react": "^16.6.3","react-dom": "^16.6.3","react-scripts": "2.1.1","reactstrap": "^6.5.0"},
  1. We'll make a default Component directory inside the /src folder and create our first component.
cd client/src && mkdir components && cd components && touch Button.js
  1. Open your Button.js file and lets create a sample button to activate our call function to the API.
importReact,{Component}from"react";classButtonextendsComponent{render(){return(<div><divclass="card container mt-3"><divclass="card-body"><divclass="row"><center><buttonclass="btn btn-primary">Test Call!</button></center></div></div></div></div>);}}exportdefaultButton;
  1. Start your server npm start and check if your bootstrap import works as well as the test button! If all is displaying then we are almost done. We are sooooo close!

We want our button to actually call the API now so lets create the function with the appropriate call. We want to add an onclick event to the button html like so:

<buttonclass="btn btn-primary"onClick={this.callApi}>
Test Call!
</button>

and our custom function PLUS the initial state set to null

state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};

After copying and pasting both snippets inside the Button.js file, we fetch from the url http://localhost:3000/api/v1/movies in a json format and once we return a true response we will set the response to the data variable and console log the results into the browser.

This should be the complete Button.js file below!

importReact,{Component}from"react";classButtonextendsComponent{state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};render(){return(<div><divclassName="card container mt-3"><divclassName="card-body"><divclassName="row"><center><buttonclassName="btn btn-primary"onClick={this.callApi}>
Test Call!
</button><br/></center><br/><br/><br/><br/><br/><pclassName="m-5">{this.state.results.map(obj=><li>{obj.name}</li>)}</p></div></div></div></div>);}}exportdefaultButton;
  1. Finally, let's open our App.js file in the /src directory to add our new Button Component to the App itself. Check below to see the example. Don't forget that we need to enclose the <Button /> in two <div></div> tags!
importReact,{Component}from'react';importlogofrom'./logo.svg';import'./App.css';importButtonfrom'./components/Button';classAppextendsComponent{render(){return(<div><Button/></div>);}}exportdefaultApp;

This should be everything we need to setup the API. Simply click our test api call button and see the magic work!

Congratulations! Our Rails API and React Client is done! If you enjoyed this API tutorial please give it a star and share it with your friends!

Rails Serializers

What are Serializers? Well Rails API's returns JSON data in full, so serializers allows us to cherry pick the exact data we want in a much organized fashion. Instead of getting every column from the returned data, we can grab which ever we allow to pass through.

Normal ModelSerializer Model
id, name, rating, director, score, actors_id, created_at, updated_atid, name, rating

We are able to tell the Rails API what to fetch rather than the frontend; making it much more simple and faster to scaffold your next project.

  1. Installation

Open your gemfile and add the serializer gem into your project. Don't forget to bundle install !

# Serializergem'active_model_serializers'

We want to create a clone of any current model we have so when we make requests in the backend, the request will read the serializer file first, then it will find the rails model/controller to finisht the request. We have a model called Movie so we'll duplicate that by running:

rails g serializer movie

You can see that a new directory was made in the app/ directory and we now have app/serializers/movie_serializer file in our project.

Let's open that file and see what we have:

classMovieSerializer < ActiveModel::Serializerattributes:idend

We have our Movie Class inheriting from the serializer class on the first line, and the returned attribute on the second. So far the default returned attribute is just an ID. Let's test this now!

1a. Turn on your rails server and go to the url localhost:3000/api/v1/movies

You should see that only the id attribute is being returned from the database.

{
id: 1
},
{
id: 2
},
{
id: 3
}

You can add any attribute to your liking to the serializer file for your next big project. But that's the end of the serializer section!

About

📱A Rails 5 API backend React JS Frontend Guide 💞

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - wkhatch/Rails-API-React-Tutorial: 📱A Rails 5 API backend React JS Frontend Guide 💞 · GitHub
Skip to content

Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Rails-API-React-Tutorial 💻 Open Source Love

Hey! This is a super-easy to follow Rails/React API tutorial that is fully in depth from start to finish. This guide shows you how to install Ruby and Rails 5 in a Virtual Box, React JS via create-react-app and connecting the frontend and backend.

Table of Contents

Downloading Virtual Box

  • Why Virtual Box? What is it? We'll be using Ubuntu to work with our rails applications so it'll be more organized for us to be working in a virtual enviorment! You can always destroy the enviorment and reconfigure whenever you want.
  1. Download VirtualBox 5.2.22 for Mac OSX here, or Windows here
  2. Run the installer.
  3. Download Vagrant for Mac OSX here, or Windows here
  4. Let's create our first enviorment. You can run the script below to keep your rails projects on your Desktop.
cd /Desktop && mkdir rails && cd rails && vagrant init
  1. Download the OS to VirtualBox
vagrant box add ubuntu/trusty64
  1. Double check and make sure our new box is there
vagrant box list
  1. Add this script to the Vagrant File
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
end
  1. Start the vagrant server
vagrant up && vagrant ssh
  1. Direct yourself to the vagrant directory
cd /vagrant
  1. Add our Bootstrap File
mkdir new_project && cd new_project && touch bootstrap.sh
  1. Copy this script to configure our virtual enviorment
#!/usr/bin/env bash
# upgrade and update the system
echo upgrading and updating the system
sudo apt-get update
sudo apt-get -y upgrade
# install node.js for js runtime when using Rails
echo installing nodejs for ExecJS runtime and git
sudo apt-get install -y nodejs
sudo apt-get install -y git
# install RVM
echo installing RVM
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash -s stable
source /home/vagrant/.rvm/scripts/rvm
rvm requirements
# install Ruby and make 2.3.1 the default
echo installing ruby
rvm install 2.3.1
rvm use 2.3.1 --default
# install Bundler and Rails
echo installing bundler and rails
gem install bundler --no-ri --no-rdoc
gem install rails -v 4.2.7 --no-ri --no-rdoc
# install postgres and its dependencies
echo installing psql and its dependencies
sudo apt-get install -y postgresql postgresql-contrib libpq-dev
  1. Re-edit the vagrant file for our newest editions + new bootstrap file
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network "forwarded_port", guest: 3000, host: 3000, host_ip: "127.0.0.1"
config.vm.provision :shell, path: "bootstrap.sh", privileged: false
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--memory", "2048"]
vb.customize ["modifyvm", :id, "--cpus", "2"]
end
end
  1. Open a new tab in your terminal and lets test the vagrant configs
vagrant halt && vagrant up --provision
  1. Last step. whew...! Once your vagrant server is on (vagrant up and vagrant ssh!), check that Ruby and Rails was installed!
ruby -v

Downloading create-react-app

First we need Node Packet Manager if you dont already. You can download it here. Run the installer and save settings so npm is saved globally.

Let's begin!

  1. run npm install -g create-react-app and let the files download to your drive.

1a. If you are running problems with the ERR! message, try using sudo to run privileges as administrator.

  1. Let's create a test app to see if everything is running smoothly. type create-react-app my-cool-app in the command line and see if everything installs. my-cool-app will be the name of your react project.

  2. Run npm start and type Y in case there are some conflicting port configs in your local host. You should see the bottom image in your browser if everything was installed correctly!

Image and video hosting by TinyPic

Rails API 💎

Now that have our virtual enviorment ready, we can create our first ever Rails API. The new rails api command scaffolds everything we need to get up and ready for our project. Let's start our vagrant server and ssh into our project folder.

  1. Run the following: rails new my-first-api --api -T

What's going on here? The --api command tells rails that we want an API structure application instead of a standard rails structure. The -T command also tells rails that we don't want Minitest as our testing suite. You'll most likely be used to Rspec so we'll talk about that later in the guide.

  1. Enable Cross-Origin Resource Sharing (CORS) in your gem and config directory. Locate your gemfile and uncomment the following
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possiblegem'rack-cors'

Do not forget to bundle install !

Now in your config/initializers directory, you should now see a cors.rb file. Add the following to

# config/initializers/cors.rbclassApplication < Rails::Applicationconfig.middleware.insert_before0,"Rack::Cors"doallowdoorigins'*'resource'*',:headers=>:any,:methods=>[:get,:post,:patch,:options]endendend

Since this tutorial is mainly for testing and toy projects, we are allowing ALL methods from another domain. You should tailor the header and methods to your liking.

Rails API Versioning

Versioning is the process of seperating and creating new features/data/endpoints for your API. Since this is our first API, let's make our test-api v1.

  1. Run the following in your terminal
mkdir mkdir app/controllers/api && mkdir app/controllers/api/v1

If everything looks right you should see your directory identical as below.

Image and video hosting by TinyPic

Now that our versioning is complete, let's test out a model and controller to work with our new url of localhost:3000/api/v1.

  1. Let's scaffold a test model/controller and call it movies
railsgscaffoldMoviesname:stringrating:integerrailsdb:migrate

The Rails engine creates your controller in the default /controllers directory but we need to move our new controller into the api/v1 directory.

  1. You can either move it manually or the following:
mv app/controllers/movies_controller.rb app/controllers/api/v1
  1. Update the Movies Controller

Our newly generated controller does not properly inherit from the namespace api/v1 (We will update the routes later in the tutorial) so let's change our controller class from

classMoviesController < ApplicationController

TO

classApi::V1::MoviesController < ApplicationController
  1. Update the Routes Locate to your config folder and open your routes.rb file.
Rails.application.routes.drawdoresources:moviesend

If we go to localhost:3000/movies we will not call the controller. We must update our Routes to:

Rails.application.routes.drawdonamespace:apidonamespace:v1doresources:moviesendendend

which allows us to call the json data from localhost:3000/api/v1/movies

  1. Let's seed our sqlite database with some classic movies so we can practice getting data with GET requests to the API.

Copy and paste the following data to your db/seeds.rb file.

Movie.create(name: "The Nightmare Before Christmas",rating: 5)Movie.create(name: "Titanic",rating: 5)Movie.create(name: "Venom",rating: 4)Movie.create(name: "A Quiet Place",rating: 5)Movie.create(name: "Nobody's Fool",rating: 2)Movie.create(name: "Suspiria",rating: 4)Movie.create(name: "Hereditary",rating: 4)Movie.create(name: "Office Space",rating: 5)Movie.create(name: "Elf",rating: 4)Movie.create(name: "Dawn of the Planet of the Apes",rating: 3)Movie.create(name: "Secret life of Pets",rating: 4)Movie.create(name: "Overlord",rating: 3)Movie.create(name: "Wonder Woman",rating: 5)Movie.create(name: "Bohemian Rhapsody",rating: 4)Movie.create(name: "Ocean's 8",rating: 5)

Seed the DB using rails db:seed && rails db:migrate

  1. Test the API using a GET request.

Start your Rails server rails s and navigate to localhost:3000/api/v1/movies and if it is successful you should see the following JSON output:

(Optional) I'm using a pretty JSON viewer for chrome which you can download here.Image and video hosting by TinyPic

Congrats! You have successfully created a Rails API and completed your first GET request!

Downloading React into our Project

React is a component based front end framework that makes it easy to make frontend calls to our Rails API. Let's make this organized as possible and add our react directory inside our rails app.

  1. Open your terminal and create a new project inside your API.
create-react-app client

Image and video hosting by TinyPic
  1. Download Boostrap into the react directory:
npm install --save reactstrap bootstrap@4

Then open your index.js file inside the /src directory and add the following import line:

importReactfrom"react";importReactDOMfrom"react-dom";import"./index.css";importAppfrom"./App";import*asserviceWorkerfrom"./serviceWorker";// Import goes below for Bootstrapimport"bootstrap/dist/css/bootstrap.css";
  1. Let's proxy our client so we know where to get the requests from!

Open package.json from our react folder and add the following json code to your package.

"proxy": "http://127.0.0.1:3000",

Heres mine as an example!

{"name": "client","version": "0.1.0","private": true,"proxy": "http://127.0.0.1:3000","dependencies": {"bootstrap": "^4.1.3","react": "^16.6.3","react-dom": "^16.6.3","react-scripts": "2.1.1","reactstrap": "^6.5.0"},
  1. We'll make a default Component directory inside the /src folder and create our first component.
cd client/src && mkdir components && cd components && touch Button.js
  1. Open your Button.js file and lets create a sample button to activate our call function to the API.
importReact,{Component}from"react";classButtonextendsComponent{render(){return(<div><divclass="card container mt-3"><divclass="card-body"><divclass="row"><center><buttonclass="btn btn-primary">Test Call!</button></center></div></div></div></div>);}}exportdefaultButton;
  1. Start your server npm start and check if your bootstrap import works as well as the test button! If all is displaying then we are almost done. We are sooooo close!

We want our button to actually call the API now so lets create the function with the appropriate call. We want to add an onclick event to the button html like so:

<buttonclass="btn btn-primary"onClick={this.callApi}>
Test Call!
</button>

and our custom function PLUS the initial state set to null

state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};

After copying and pasting both snippets inside the Button.js file, we fetch from the url http://localhost:3000/api/v1/movies in a json format and once we return a true response we will set the response to the data variable and console log the results into the browser.

This should be the complete Button.js file below!

importReact,{Component}from"react";classButtonextendsComponent{state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};render(){return(<div><divclassName="card container mt-3"><divclassName="card-body"><divclassName="row"><center><buttonclassName="btn btn-primary"onClick={this.callApi}>
Test Call!
</button><br/></center><br/><br/><br/><br/><br/><pclassName="m-5">{this.state.results.map(obj=><li>{obj.name}</li>)}</p></div></div></div></div>);}}exportdefaultButton;
  1. Finally, let's open our App.js file in the /src directory to add our new Button Component to the App itself. Check below to see the example. Don't forget that we need to enclose the <Button /> in two <div></div> tags!
importReact,{Component}from'react';importlogofrom'./logo.svg';import'./App.css';importButtonfrom'./components/Button';classAppextendsComponent{render(){return(<div><Button/></div>);}}exportdefaultApp;

This should be everything we need to setup the API. Simply click our test api call button and see the magic work!

Congratulations! Our Rails API and React Client is done! If you enjoyed this API tutorial please give it a star and share it with your friends!

Rails Serializers

What are Serializers? Well Rails API's returns JSON data in full, so serializers allows us to cherry pick the exact data we want in a much organized fashion. Instead of getting every column from the returned data, we can grab which ever we allow to pass through.

Normal ModelSerializer Model
id, name, rating, director, score, actors_id, created_at, updated_atid, name, rating

We are able to tell the Rails API what to fetch rather than the frontend; making it much more simple and faster to scaffold your next project.

  1. Installation

Open your gemfile and add the serializer gem into your project. Don't forget to bundle install !

# Serializergem'active_model_serializers'

We want to create a clone of any current model we have so when we make requests in the backend, the request will read the serializer file first, then it will find the rails model/controller to finisht the request. We have a model called Movie so we'll duplicate that by running:

rails g serializer movie

You can see that a new directory was made in the app/ directory and we now have app/serializers/movie_serializer file in our project.

Let's open that file and see what we have:

classMovieSerializer < ActiveModel::Serializerattributes:idend

We have our Movie Class inheriting from the serializer class on the first line, and the returned attribute on the second. So far the default returned attribute is just an ID. Let's test this now!

1a. Turn on your rails server and go to the url localhost:3000/api/v1/movies

You should see that only the id attribute is being returned from the database.

{
id: 1
},
{
id: 2
},
{
id: 3
}

You can add any attribute to your liking to the serializer file for your next big project. But that's the end of the serializer section!

About

📱A Rails 5 API backend React JS Frontend Guide 💞

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - wkhatch/Rails-API-React-Tutorial: 📱A Rails 5 API backend React JS Frontend Guide 💞 · GitHub
Skip to content

Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Rails-API-React-Tutorial 💻 Open Source Love

Hey! This is a super-easy to follow Rails/React API tutorial that is fully in depth from start to finish. This guide shows you how to install Ruby and Rails 5 in a Virtual Box, React JS via create-react-app and connecting the frontend and backend.

Table of Contents

Downloading Virtual Box

  • Why Virtual Box? What is it? We'll be using Ubuntu to work with our rails applications so it'll be more organized for us to be working in a virtual enviorment! You can always destroy the enviorment and reconfigure whenever you want.
  1. Download VirtualBox 5.2.22 for Mac OSX here, or Windows here
  2. Run the installer.
  3. Download Vagrant for Mac OSX here, or Windows here
  4. Let's create our first enviorment. You can run the script below to keep your rails projects on your Desktop.
cd /Desktop && mkdir rails && cd rails && vagrant init
  1. Download the OS to VirtualBox
vagrant box add ubuntu/trusty64
  1. Double check and make sure our new box is there
vagrant box list
  1. Add this script to the Vagrant File
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
end
  1. Start the vagrant server
vagrant up && vagrant ssh
  1. Direct yourself to the vagrant directory
cd /vagrant
  1. Add our Bootstrap File
mkdir new_project && cd new_project && touch bootstrap.sh
  1. Copy this script to configure our virtual enviorment
#!/usr/bin/env bash
# upgrade and update the system
echo upgrading and updating the system
sudo apt-get update
sudo apt-get -y upgrade
# install node.js for js runtime when using Rails
echo installing nodejs for ExecJS runtime and git
sudo apt-get install -y nodejs
sudo apt-get install -y git
# install RVM
echo installing RVM
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash -s stable
source /home/vagrant/.rvm/scripts/rvm
rvm requirements
# install Ruby and make 2.3.1 the default
echo installing ruby
rvm install 2.3.1
rvm use 2.3.1 --default
# install Bundler and Rails
echo installing bundler and rails
gem install bundler --no-ri --no-rdoc
gem install rails -v 4.2.7 --no-ri --no-rdoc
# install postgres and its dependencies
echo installing psql and its dependencies
sudo apt-get install -y postgresql postgresql-contrib libpq-dev
  1. Re-edit the vagrant file for our newest editions + new bootstrap file
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network "forwarded_port", guest: 3000, host: 3000, host_ip: "127.0.0.1"
config.vm.provision :shell, path: "bootstrap.sh", privileged: false
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--memory", "2048"]
vb.customize ["modifyvm", :id, "--cpus", "2"]
end
end
  1. Open a new tab in your terminal and lets test the vagrant configs
vagrant halt && vagrant up --provision
  1. Last step. whew...! Once your vagrant server is on (vagrant up and vagrant ssh!), check that Ruby and Rails was installed!
ruby -v

Downloading create-react-app

First we need Node Packet Manager if you dont already. You can download it here. Run the installer and save settings so npm is saved globally.

Let's begin!

  1. run npm install -g create-react-app and let the files download to your drive.

1a. If you are running problems with the ERR! message, try using sudo to run privileges as administrator.

  1. Let's create a test app to see if everything is running smoothly. type create-react-app my-cool-app in the command line and see if everything installs. my-cool-app will be the name of your react project.

  2. Run npm start and type Y in case there are some conflicting port configs in your local host. You should see the bottom image in your browser if everything was installed correctly!

Image and video hosting by TinyPic

Rails API 💎

Now that have our virtual enviorment ready, we can create our first ever Rails API. The new rails api command scaffolds everything we need to get up and ready for our project. Let's start our vagrant server and ssh into our project folder.

  1. Run the following: rails new my-first-api --api -T

What's going on here? The --api command tells rails that we want an API structure application instead of a standard rails structure. The -T command also tells rails that we don't want Minitest as our testing suite. You'll most likely be used to Rspec so we'll talk about that later in the guide.

  1. Enable Cross-Origin Resource Sharing (CORS) in your gem and config directory. Locate your gemfile and uncomment the following
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possiblegem'rack-cors'

Do not forget to bundle install !

Now in your config/initializers directory, you should now see a cors.rb file. Add the following to

# config/initializers/cors.rbclassApplication < Rails::Applicationconfig.middleware.insert_before0,"Rack::Cors"doallowdoorigins'*'resource'*',:headers=>:any,:methods=>[:get,:post,:patch,:options]endendend

Since this tutorial is mainly for testing and toy projects, we are allowing ALL methods from another domain. You should tailor the header and methods to your liking.

Rails API Versioning

Versioning is the process of seperating and creating new features/data/endpoints for your API. Since this is our first API, let's make our test-api v1.

  1. Run the following in your terminal
mkdir mkdir app/controllers/api && mkdir app/controllers/api/v1

If everything looks right you should see your directory identical as below.

Image and video hosting by TinyPic

Now that our versioning is complete, let's test out a model and controller to work with our new url of localhost:3000/api/v1.

  1. Let's scaffold a test model/controller and call it movies
railsgscaffoldMoviesname:stringrating:integerrailsdb:migrate

The Rails engine creates your controller in the default /controllers directory but we need to move our new controller into the api/v1 directory.

  1. You can either move it manually or the following:
mv app/controllers/movies_controller.rb app/controllers/api/v1
  1. Update the Movies Controller

Our newly generated controller does not properly inherit from the namespace api/v1 (We will update the routes later in the tutorial) so let's change our controller class from

classMoviesController < ApplicationController

TO

classApi::V1::MoviesController < ApplicationController
  1. Update the Routes Locate to your config folder and open your routes.rb file.
Rails.application.routes.drawdoresources:moviesend

If we go to localhost:3000/movies we will not call the controller. We must update our Routes to:

Rails.application.routes.drawdonamespace:apidonamespace:v1doresources:moviesendendend

which allows us to call the json data from localhost:3000/api/v1/movies

  1. Let's seed our sqlite database with some classic movies so we can practice getting data with GET requests to the API.

Copy and paste the following data to your db/seeds.rb file.

Movie.create(name: "The Nightmare Before Christmas",rating: 5)Movie.create(name: "Titanic",rating: 5)Movie.create(name: "Venom",rating: 4)Movie.create(name: "A Quiet Place",rating: 5)Movie.create(name: "Nobody's Fool",rating: 2)Movie.create(name: "Suspiria",rating: 4)Movie.create(name: "Hereditary",rating: 4)Movie.create(name: "Office Space",rating: 5)Movie.create(name: "Elf",rating: 4)Movie.create(name: "Dawn of the Planet of the Apes",rating: 3)Movie.create(name: "Secret life of Pets",rating: 4)Movie.create(name: "Overlord",rating: 3)Movie.create(name: "Wonder Woman",rating: 5)Movie.create(name: "Bohemian Rhapsody",rating: 4)Movie.create(name: "Ocean's 8",rating: 5)

Seed the DB using rails db:seed && rails db:migrate

  1. Test the API using a GET request.

Start your Rails server rails s and navigate to localhost:3000/api/v1/movies and if it is successful you should see the following JSON output:

(Optional) I'm using a pretty JSON viewer for chrome which you can download here.Image and video hosting by TinyPic

Congrats! You have successfully created a Rails API and completed your first GET request!

Downloading React into our Project

React is a component based front end framework that makes it easy to make frontend calls to our Rails API. Let's make this organized as possible and add our react directory inside our rails app.

  1. Open your terminal and create a new project inside your API.
create-react-app client

Image and video hosting by TinyPic
  1. Download Boostrap into the react directory:
npm install --save reactstrap bootstrap@4

Then open your index.js file inside the /src directory and add the following import line:

importReactfrom"react";importReactDOMfrom"react-dom";import"./index.css";importAppfrom"./App";import*asserviceWorkerfrom"./serviceWorker";// Import goes below for Bootstrapimport"bootstrap/dist/css/bootstrap.css";
  1. Let's proxy our client so we know where to get the requests from!

Open package.json from our react folder and add the following json code to your package.

"proxy": "http://127.0.0.1:3000",

Heres mine as an example!

{"name": "client","version": "0.1.0","private": true,"proxy": "http://127.0.0.1:3000","dependencies": {"bootstrap": "^4.1.3","react": "^16.6.3","react-dom": "^16.6.3","react-scripts": "2.1.1","reactstrap": "^6.5.0"},
  1. We'll make a default Component directory inside the /src folder and create our first component.
cd client/src && mkdir components && cd components && touch Button.js
  1. Open your Button.js file and lets create a sample button to activate our call function to the API.
importReact,{Component}from"react";classButtonextendsComponent{render(){return(<div><divclass="card container mt-3"><divclass="card-body"><divclass="row"><center><buttonclass="btn btn-primary">Test Call!</button></center></div></div></div></div>);}}exportdefaultButton;
  1. Start your server npm start and check if your bootstrap import works as well as the test button! If all is displaying then we are almost done. We are sooooo close!

We want our button to actually call the API now so lets create the function with the appropriate call. We want to add an onclick event to the button html like so:

<buttonclass="btn btn-primary"onClick={this.callApi}>
Test Call!
</button>

and our custom function PLUS the initial state set to null

state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};

After copying and pasting both snippets inside the Button.js file, we fetch from the url http://localhost:3000/api/v1/movies in a json format and once we return a true response we will set the response to the data variable and console log the results into the browser.

This should be the complete Button.js file below!

importReact,{Component}from"react";classButtonextendsComponent{state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};render(){return(<div><divclassName="card container mt-3"><divclassName="card-body"><divclassName="row"><center><buttonclassName="btn btn-primary"onClick={this.callApi}>
Test Call!
</button><br/></center><br/><br/><br/><br/><br/><pclassName="m-5">{this.state.results.map(obj=><li>{obj.name}</li>)}</p></div></div></div></div>);}}exportdefaultButton;
  1. Finally, let's open our App.js file in the /src directory to add our new Button Component to the App itself. Check below to see the example. Don't forget that we need to enclose the <Button /> in two <div></div> tags!
importReact,{Component}from'react';importlogofrom'./logo.svg';import'./App.css';importButtonfrom'./components/Button';classAppextendsComponent{render(){return(<div><Button/></div>);}}exportdefaultApp;

This should be everything we need to setup the API. Simply click our test api call button and see the magic work!

Congratulations! Our Rails API and React Client is done! If you enjoyed this API tutorial please give it a star and share it with your friends!

Rails Serializers

What are Serializers? Well Rails API's returns JSON data in full, so serializers allows us to cherry pick the exact data we want in a much organized fashion. Instead of getting every column from the returned data, we can grab which ever we allow to pass through.

Normal ModelSerializer Model
id, name, rating, director, score, actors_id, created_at, updated_atid, name, rating

We are able to tell the Rails API what to fetch rather than the frontend; making it much more simple and faster to scaffold your next project.

  1. Installation

Open your gemfile and add the serializer gem into your project. Don't forget to bundle install !

# Serializergem'active_model_serializers'

We want to create a clone of any current model we have so when we make requests in the backend, the request will read the serializer file first, then it will find the rails model/controller to finisht the request. We have a model called Movie so we'll duplicate that by running:

rails g serializer movie

You can see that a new directory was made in the app/ directory and we now have app/serializers/movie_serializer file in our project.

Let's open that file and see what we have:

classMovieSerializer < ActiveModel::Serializerattributes:idend

We have our Movie Class inheriting from the serializer class on the first line, and the returned attribute on the second. So far the default returned attribute is just an ID. Let's test this now!

1a. Turn on your rails server and go to the url localhost:3000/api/v1/movies

You should see that only the id attribute is being returned from the database.

{
id: 1
},
{
id: 2
},
{
id: 3
}

You can add any attribute to your liking to the serializer file for your next big project. But that's the end of the serializer section!

About

📱A Rails 5 API backend React JS Frontend Guide 💞

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - wkhatch/Rails-API-React-Tutorial: 📱A Rails 5 API backend React JS Frontend Guide 💞 · GitHub
Skip to content

Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Rails-API-React-Tutorial 💻 Open Source Love

Hey! This is a super-easy to follow Rails/React API tutorial that is fully in depth from start to finish. This guide shows you how to install Ruby and Rails 5 in a Virtual Box, React JS via create-react-app and connecting the frontend and backend.

Table of Contents

Downloading Virtual Box

  • Why Virtual Box? What is it? We'll be using Ubuntu to work with our rails applications so it'll be more organized for us to be working in a virtual enviorment! You can always destroy the enviorment and reconfigure whenever you want.
  1. Download VirtualBox 5.2.22 for Mac OSX here, or Windows here
  2. Run the installer.
  3. Download Vagrant for Mac OSX here, or Windows here
  4. Let's create our first enviorment. You can run the script below to keep your rails projects on your Desktop.
cd /Desktop && mkdir rails && cd rails && vagrant init
  1. Download the OS to VirtualBox
vagrant box add ubuntu/trusty64
  1. Double check and make sure our new box is there
vagrant box list
  1. Add this script to the Vagrant File
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
end
  1. Start the vagrant server
vagrant up && vagrant ssh
  1. Direct yourself to the vagrant directory
cd /vagrant
  1. Add our Bootstrap File
mkdir new_project && cd new_project && touch bootstrap.sh
  1. Copy this script to configure our virtual enviorment
#!/usr/bin/env bash
# upgrade and update the system
echo upgrading and updating the system
sudo apt-get update
sudo apt-get -y upgrade
# install node.js for js runtime when using Rails
echo installing nodejs for ExecJS runtime and git
sudo apt-get install -y nodejs
sudo apt-get install -y git
# install RVM
echo installing RVM
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash -s stable
source /home/vagrant/.rvm/scripts/rvm
rvm requirements
# install Ruby and make 2.3.1 the default
echo installing ruby
rvm install 2.3.1
rvm use 2.3.1 --default
# install Bundler and Rails
echo installing bundler and rails
gem install bundler --no-ri --no-rdoc
gem install rails -v 4.2.7 --no-ri --no-rdoc
# install postgres and its dependencies
echo installing psql and its dependencies
sudo apt-get install -y postgresql postgresql-contrib libpq-dev
  1. Re-edit the vagrant file for our newest editions + new bootstrap file
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network "forwarded_port", guest: 3000, host: 3000, host_ip: "127.0.0.1"
config.vm.provision :shell, path: "bootstrap.sh", privileged: false
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--memory", "2048"]
vb.customize ["modifyvm", :id, "--cpus", "2"]
end
end
  1. Open a new tab in your terminal and lets test the vagrant configs
vagrant halt && vagrant up --provision
  1. Last step. whew...! Once your vagrant server is on (vagrant up and vagrant ssh!), check that Ruby and Rails was installed!
ruby -v

Downloading create-react-app

First we need Node Packet Manager if you dont already. You can download it here. Run the installer and save settings so npm is saved globally.

Let's begin!

  1. run npm install -g create-react-app and let the files download to your drive.

1a. If you are running problems with the ERR! message, try using sudo to run privileges as administrator.

  1. Let's create a test app to see if everything is running smoothly. type create-react-app my-cool-app in the command line and see if everything installs. my-cool-app will be the name of your react project.

  2. Run npm start and type Y in case there are some conflicting port configs in your local host. You should see the bottom image in your browser if everything was installed correctly!

Image and video hosting by TinyPic

Rails API 💎

Now that have our virtual enviorment ready, we can create our first ever Rails API. The new rails api command scaffolds everything we need to get up and ready for our project. Let's start our vagrant server and ssh into our project folder.

  1. Run the following: rails new my-first-api --api -T

What's going on here? The --api command tells rails that we want an API structure application instead of a standard rails structure. The -T command also tells rails that we don't want Minitest as our testing suite. You'll most likely be used to Rspec so we'll talk about that later in the guide.

  1. Enable Cross-Origin Resource Sharing (CORS) in your gem and config directory. Locate your gemfile and uncomment the following
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possiblegem'rack-cors'

Do not forget to bundle install !

Now in your config/initializers directory, you should now see a cors.rb file. Add the following to

# config/initializers/cors.rbclassApplication < Rails::Applicationconfig.middleware.insert_before0,"Rack::Cors"doallowdoorigins'*'resource'*',:headers=>:any,:methods=>[:get,:post,:patch,:options]endendend

Since this tutorial is mainly for testing and toy projects, we are allowing ALL methods from another domain. You should tailor the header and methods to your liking.

Rails API Versioning

Versioning is the process of seperating and creating new features/data/endpoints for your API. Since this is our first API, let's make our test-api v1.

  1. Run the following in your terminal
mkdir mkdir app/controllers/api && mkdir app/controllers/api/v1

If everything looks right you should see your directory identical as below.

Image and video hosting by TinyPic

Now that our versioning is complete, let's test out a model and controller to work with our new url of localhost:3000/api/v1.

  1. Let's scaffold a test model/controller and call it movies
railsgscaffoldMoviesname:stringrating:integerrailsdb:migrate

The Rails engine creates your controller in the default /controllers directory but we need to move our new controller into the api/v1 directory.

  1. You can either move it manually or the following:
mv app/controllers/movies_controller.rb app/controllers/api/v1
  1. Update the Movies Controller

Our newly generated controller does not properly inherit from the namespace api/v1 (We will update the routes later in the tutorial) so let's change our controller class from

classMoviesController < ApplicationController

TO

classApi::V1::MoviesController < ApplicationController
  1. Update the Routes Locate to your config folder and open your routes.rb file.
Rails.application.routes.drawdoresources:moviesend

If we go to localhost:3000/movies we will not call the controller. We must update our Routes to:

Rails.application.routes.drawdonamespace:apidonamespace:v1doresources:moviesendendend

which allows us to call the json data from localhost:3000/api/v1/movies

  1. Let's seed our sqlite database with some classic movies so we can practice getting data with GET requests to the API.

Copy and paste the following data to your db/seeds.rb file.

Movie.create(name: "The Nightmare Before Christmas",rating: 5)Movie.create(name: "Titanic",rating: 5)Movie.create(name: "Venom",rating: 4)Movie.create(name: "A Quiet Place",rating: 5)Movie.create(name: "Nobody's Fool",rating: 2)Movie.create(name: "Suspiria",rating: 4)Movie.create(name: "Hereditary",rating: 4)Movie.create(name: "Office Space",rating: 5)Movie.create(name: "Elf",rating: 4)Movie.create(name: "Dawn of the Planet of the Apes",rating: 3)Movie.create(name: "Secret life of Pets",rating: 4)Movie.create(name: "Overlord",rating: 3)Movie.create(name: "Wonder Woman",rating: 5)Movie.create(name: "Bohemian Rhapsody",rating: 4)Movie.create(name: "Ocean's 8",rating: 5)

Seed the DB using rails db:seed && rails db:migrate

  1. Test the API using a GET request.

Start your Rails server rails s and navigate to localhost:3000/api/v1/movies and if it is successful you should see the following JSON output:

(Optional) I'm using a pretty JSON viewer for chrome which you can download here.Image and video hosting by TinyPic

Congrats! You have successfully created a Rails API and completed your first GET request!

Downloading React into our Project

React is a component based front end framework that makes it easy to make frontend calls to our Rails API. Let's make this organized as possible and add our react directory inside our rails app.

  1. Open your terminal and create a new project inside your API.
create-react-app client

Image and video hosting by TinyPic
  1. Download Boostrap into the react directory:
npm install --save reactstrap bootstrap@4

Then open your index.js file inside the /src directory and add the following import line:

importReactfrom"react";importReactDOMfrom"react-dom";import"./index.css";importAppfrom"./App";import*asserviceWorkerfrom"./serviceWorker";// Import goes below for Bootstrapimport"bootstrap/dist/css/bootstrap.css";
  1. Let's proxy our client so we know where to get the requests from!

Open package.json from our react folder and add the following json code to your package.

"proxy": "http://127.0.0.1:3000",

Heres mine as an example!

{"name": "client","version": "0.1.0","private": true,"proxy": "http://127.0.0.1:3000","dependencies": {"bootstrap": "^4.1.3","react": "^16.6.3","react-dom": "^16.6.3","react-scripts": "2.1.1","reactstrap": "^6.5.0"},
  1. We'll make a default Component directory inside the /src folder and create our first component.
cd client/src && mkdir components && cd components && touch Button.js
  1. Open your Button.js file and lets create a sample button to activate our call function to the API.
importReact,{Component}from"react";classButtonextendsComponent{render(){return(<div><divclass="card container mt-3"><divclass="card-body"><divclass="row"><center><buttonclass="btn btn-primary">Test Call!</button></center></div></div></div></div>);}}exportdefaultButton;
  1. Start your server npm start and check if your bootstrap import works as well as the test button! If all is displaying then we are almost done. We are sooooo close!

We want our button to actually call the API now so lets create the function with the appropriate call. We want to add an onclick event to the button html like so:

<buttonclass="btn btn-primary"onClick={this.callApi}>
Test Call!
</button>

and our custom function PLUS the initial state set to null

state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};

After copying and pasting both snippets inside the Button.js file, we fetch from the url http://localhost:3000/api/v1/movies in a json format and once we return a true response we will set the response to the data variable and console log the results into the browser.

This should be the complete Button.js file below!

importReact,{Component}from"react";classButtonextendsComponent{state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};render(){return(<div><divclassName="card container mt-3"><divclassName="card-body"><divclassName="row"><center><buttonclassName="btn btn-primary"onClick={this.callApi}>
Test Call!
</button><br/></center><br/><br/><br/><br/><br/><pclassName="m-5">{this.state.results.map(obj=><li>{obj.name}</li>)}</p></div></div></div></div>);}}exportdefaultButton;
  1. Finally, let's open our App.js file in the /src directory to add our new Button Component to the App itself. Check below to see the example. Don't forget that we need to enclose the <Button /> in two <div></div> tags!
importReact,{Component}from'react';importlogofrom'./logo.svg';import'./App.css';importButtonfrom'./components/Button';classAppextendsComponent{render(){return(<div><Button/></div>);}}exportdefaultApp;

This should be everything we need to setup the API. Simply click our test api call button and see the magic work!

Congratulations! Our Rails API and React Client is done! If you enjoyed this API tutorial please give it a star and share it with your friends!

Rails Serializers

What are Serializers? Well Rails API's returns JSON data in full, so serializers allows us to cherry pick the exact data we want in a much organized fashion. Instead of getting every column from the returned data, we can grab which ever we allow to pass through.

Normal ModelSerializer Model
id, name, rating, director, score, actors_id, created_at, updated_atid, name, rating

We are able to tell the Rails API what to fetch rather than the frontend; making it much more simple and faster to scaffold your next project.

  1. Installation

Open your gemfile and add the serializer gem into your project. Don't forget to bundle install !

# Serializergem'active_model_serializers'

We want to create a clone of any current model we have so when we make requests in the backend, the request will read the serializer file first, then it will find the rails model/controller to finisht the request. We have a model called Movie so we'll duplicate that by running:

rails g serializer movie

You can see that a new directory was made in the app/ directory and we now have app/serializers/movie_serializer file in our project.

Let's open that file and see what we have:

classMovieSerializer < ActiveModel::Serializerattributes:idend

We have our Movie Class inheriting from the serializer class on the first line, and the returned attribute on the second. So far the default returned attribute is just an ID. Let's test this now!

1a. Turn on your rails server and go to the url localhost:3000/api/v1/movies

You should see that only the id attribute is being returned from the database.

{
id: 1
},
{
id: 2
},
{
id: 3
}

You can add any attribute to your liking to the serializer file for your next big project. But that's the end of the serializer section!

About

📱A Rails 5 API backend React JS Frontend Guide 💞

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - wkhatch/Rails-API-React-Tutorial: 📱A Rails 5 API backend React JS Frontend Guide 💞 · GitHub
Skip to content

Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Rails-API-React-Tutorial 💻 Open Source Love

Hey! This is a super-easy to follow Rails/React API tutorial that is fully in depth from start to finish. This guide shows you how to install Ruby and Rails 5 in a Virtual Box, React JS via create-react-app and connecting the frontend and backend.

Table of Contents

Downloading Virtual Box

  • Why Virtual Box? What is it? We'll be using Ubuntu to work with our rails applications so it'll be more organized for us to be working in a virtual enviorment! You can always destroy the enviorment and reconfigure whenever you want.
  1. Download VirtualBox 5.2.22 for Mac OSX here, or Windows here
  2. Run the installer.
  3. Download Vagrant for Mac OSX here, or Windows here
  4. Let's create our first enviorment. You can run the script below to keep your rails projects on your Desktop.
cd /Desktop && mkdir rails && cd rails && vagrant init
  1. Download the OS to VirtualBox
vagrant box add ubuntu/trusty64
  1. Double check and make sure our new box is there
vagrant box list
  1. Add this script to the Vagrant File
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
end
  1. Start the vagrant server
vagrant up && vagrant ssh
  1. Direct yourself to the vagrant directory
cd /vagrant
  1. Add our Bootstrap File
mkdir new_project && cd new_project && touch bootstrap.sh
  1. Copy this script to configure our virtual enviorment
#!/usr/bin/env bash
# upgrade and update the system
echo upgrading and updating the system
sudo apt-get update
sudo apt-get -y upgrade
# install node.js for js runtime when using Rails
echo installing nodejs for ExecJS runtime and git
sudo apt-get install -y nodejs
sudo apt-get install -y git
# install RVM
echo installing RVM
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash -s stable
source /home/vagrant/.rvm/scripts/rvm
rvm requirements
# install Ruby and make 2.3.1 the default
echo installing ruby
rvm install 2.3.1
rvm use 2.3.1 --default
# install Bundler and Rails
echo installing bundler and rails
gem install bundler --no-ri --no-rdoc
gem install rails -v 4.2.7 --no-ri --no-rdoc
# install postgres and its dependencies
echo installing psql and its dependencies
sudo apt-get install -y postgresql postgresql-contrib libpq-dev
  1. Re-edit the vagrant file for our newest editions + new bootstrap file
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network "forwarded_port", guest: 3000, host: 3000, host_ip: "127.0.0.1"
config.vm.provision :shell, path: "bootstrap.sh", privileged: false
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--memory", "2048"]
vb.customize ["modifyvm", :id, "--cpus", "2"]
end
end
  1. Open a new tab in your terminal and lets test the vagrant configs
vagrant halt && vagrant up --provision
  1. Last step. whew...! Once your vagrant server is on (vagrant up and vagrant ssh!), check that Ruby and Rails was installed!
ruby -v

Downloading create-react-app

First we need Node Packet Manager if you dont already. You can download it here. Run the installer and save settings so npm is saved globally.

Let's begin!

  1. run npm install -g create-react-app and let the files download to your drive.

1a. If you are running problems with the ERR! message, try using sudo to run privileges as administrator.

  1. Let's create a test app to see if everything is running smoothly. type create-react-app my-cool-app in the command line and see if everything installs. my-cool-app will be the name of your react project.

  2. Run npm start and type Y in case there are some conflicting port configs in your local host. You should see the bottom image in your browser if everything was installed correctly!

Image and video hosting by TinyPic

Rails API 💎

Now that have our virtual enviorment ready, we can create our first ever Rails API. The new rails api command scaffolds everything we need to get up and ready for our project. Let's start our vagrant server and ssh into our project folder.

  1. Run the following: rails new my-first-api --api -T

What's going on here? The --api command tells rails that we want an API structure application instead of a standard rails structure. The -T command also tells rails that we don't want Minitest as our testing suite. You'll most likely be used to Rspec so we'll talk about that later in the guide.

  1. Enable Cross-Origin Resource Sharing (CORS) in your gem and config directory. Locate your gemfile and uncomment the following
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possiblegem'rack-cors'

Do not forget to bundle install !

Now in your config/initializers directory, you should now see a cors.rb file. Add the following to

# config/initializers/cors.rbclassApplication < Rails::Applicationconfig.middleware.insert_before0,"Rack::Cors"doallowdoorigins'*'resource'*',:headers=>:any,:methods=>[:get,:post,:patch,:options]endendend

Since this tutorial is mainly for testing and toy projects, we are allowing ALL methods from another domain. You should tailor the header and methods to your liking.

Rails API Versioning

Versioning is the process of seperating and creating new features/data/endpoints for your API. Since this is our first API, let's make our test-api v1.

  1. Run the following in your terminal
mkdir mkdir app/controllers/api && mkdir app/controllers/api/v1

If everything looks right you should see your directory identical as below.

Image and video hosting by TinyPic

Now that our versioning is complete, let's test out a model and controller to work with our new url of localhost:3000/api/v1.

  1. Let's scaffold a test model/controller and call it movies
railsgscaffoldMoviesname:stringrating:integerrailsdb:migrate

The Rails engine creates your controller in the default /controllers directory but we need to move our new controller into the api/v1 directory.

  1. You can either move it manually or the following:
mv app/controllers/movies_controller.rb app/controllers/api/v1
  1. Update the Movies Controller

Our newly generated controller does not properly inherit from the namespace api/v1 (We will update the routes later in the tutorial) so let's change our controller class from

classMoviesController < ApplicationController

TO

classApi::V1::MoviesController < ApplicationController
  1. Update the Routes Locate to your config folder and open your routes.rb file.
Rails.application.routes.drawdoresources:moviesend

If we go to localhost:3000/movies we will not call the controller. We must update our Routes to:

Rails.application.routes.drawdonamespace:apidonamespace:v1doresources:moviesendendend

which allows us to call the json data from localhost:3000/api/v1/movies

  1. Let's seed our sqlite database with some classic movies so we can practice getting data with GET requests to the API.

Copy and paste the following data to your db/seeds.rb file.

Movie.create(name: "The Nightmare Before Christmas",rating: 5)Movie.create(name: "Titanic",rating: 5)Movie.create(name: "Venom",rating: 4)Movie.create(name: "A Quiet Place",rating: 5)Movie.create(name: "Nobody's Fool",rating: 2)Movie.create(name: "Suspiria",rating: 4)Movie.create(name: "Hereditary",rating: 4)Movie.create(name: "Office Space",rating: 5)Movie.create(name: "Elf",rating: 4)Movie.create(name: "Dawn of the Planet of the Apes",rating: 3)Movie.create(name: "Secret life of Pets",rating: 4)Movie.create(name: "Overlord",rating: 3)Movie.create(name: "Wonder Woman",rating: 5)Movie.create(name: "Bohemian Rhapsody",rating: 4)Movie.create(name: "Ocean's 8",rating: 5)

Seed the DB using rails db:seed && rails db:migrate

  1. Test the API using a GET request.

Start your Rails server rails s and navigate to localhost:3000/api/v1/movies and if it is successful you should see the following JSON output:

(Optional) I'm using a pretty JSON viewer for chrome which you can download here.Image and video hosting by TinyPic

Congrats! You have successfully created a Rails API and completed your first GET request!

Downloading React into our Project

React is a component based front end framework that makes it easy to make frontend calls to our Rails API. Let's make this organized as possible and add our react directory inside our rails app.

  1. Open your terminal and create a new project inside your API.
create-react-app client

Image and video hosting by TinyPic
  1. Download Boostrap into the react directory:
npm install --save reactstrap bootstrap@4

Then open your index.js file inside the /src directory and add the following import line:

importReactfrom"react";importReactDOMfrom"react-dom";import"./index.css";importAppfrom"./App";import*asserviceWorkerfrom"./serviceWorker";// Import goes below for Bootstrapimport"bootstrap/dist/css/bootstrap.css";
  1. Let's proxy our client so we know where to get the requests from!

Open package.json from our react folder and add the following json code to your package.

"proxy": "http://127.0.0.1:3000",

Heres mine as an example!

{"name": "client","version": "0.1.0","private": true,"proxy": "http://127.0.0.1:3000","dependencies": {"bootstrap": "^4.1.3","react": "^16.6.3","react-dom": "^16.6.3","react-scripts": "2.1.1","reactstrap": "^6.5.0"},
  1. We'll make a default Component directory inside the /src folder and create our first component.
cd client/src && mkdir components && cd components && touch Button.js
  1. Open your Button.js file and lets create a sample button to activate our call function to the API.
importReact,{Component}from"react";classButtonextendsComponent{render(){return(<div><divclass="card container mt-3"><divclass="card-body"><divclass="row"><center><buttonclass="btn btn-primary">Test Call!</button></center></div></div></div></div>);}}exportdefaultButton;
  1. Start your server npm start and check if your bootstrap import works as well as the test button! If all is displaying then we are almost done. We are sooooo close!

We want our button to actually call the API now so lets create the function with the appropriate call. We want to add an onclick event to the button html like so:

<buttonclass="btn btn-primary"onClick={this.callApi}>
Test Call!
</button>

and our custom function PLUS the initial state set to null

state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};

After copying and pasting both snippets inside the Button.js file, we fetch from the url http://localhost:3000/api/v1/movies in a json format and once we return a true response we will set the response to the data variable and console log the results into the browser.

This should be the complete Button.js file below!

importReact,{Component}from"react";classButtonextendsComponent{state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};render(){return(<div><divclassName="card container mt-3"><divclassName="card-body"><divclassName="row"><center><buttonclassName="btn btn-primary"onClick={this.callApi}>
Test Call!
</button><br/></center><br/><br/><br/><br/><br/><pclassName="m-5">{this.state.results.map(obj=><li>{obj.name}</li>)}</p></div></div></div></div>);}}exportdefaultButton;
  1. Finally, let's open our App.js file in the /src directory to add our new Button Component to the App itself. Check below to see the example. Don't forget that we need to enclose the <Button /> in two <div></div> tags!
importReact,{Component}from'react';importlogofrom'./logo.svg';import'./App.css';importButtonfrom'./components/Button';classAppextendsComponent{render(){return(<div><Button/></div>);}}exportdefaultApp;

This should be everything we need to setup the API. Simply click our test api call button and see the magic work!

Congratulations! Our Rails API and React Client is done! If you enjoyed this API tutorial please give it a star and share it with your friends!

Rails Serializers

What are Serializers? Well Rails API's returns JSON data in full, so serializers allows us to cherry pick the exact data we want in a much organized fashion. Instead of getting every column from the returned data, we can grab which ever we allow to pass through.

Normal ModelSerializer Model
id, name, rating, director, score, actors_id, created_at, updated_atid, name, rating

We are able to tell the Rails API what to fetch rather than the frontend; making it much more simple and faster to scaffold your next project.

  1. Installation

Open your gemfile and add the serializer gem into your project. Don't forget to bundle install !

# Serializergem'active_model_serializers'

We want to create a clone of any current model we have so when we make requests in the backend, the request will read the serializer file first, then it will find the rails model/controller to finisht the request. We have a model called Movie so we'll duplicate that by running:

rails g serializer movie

You can see that a new directory was made in the app/ directory and we now have app/serializers/movie_serializer file in our project.

Let's open that file and see what we have:

classMovieSerializer < ActiveModel::Serializerattributes:idend

We have our Movie Class inheriting from the serializer class on the first line, and the returned attribute on the second. So far the default returned attribute is just an ID. Let's test this now!

1a. Turn on your rails server and go to the url localhost:3000/api/v1/movies

You should see that only the id attribute is being returned from the database.

{
id: 1
},
{
id: 2
},
{
id: 3
}

You can add any attribute to your liking to the serializer file for your next big project. But that's the end of the serializer section!

About

📱A Rails 5 API backend React JS Frontend Guide 💞

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - wkhatch/Rails-API-React-Tutorial: 📱A Rails 5 API backend React JS Frontend Guide 💞 · GitHub
Skip to content

Latest commit

History

54 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Rails-API-React-Tutorial 💻 Open Source Love

Hey! This is a super-easy to follow Rails/React API tutorial that is fully in depth from start to finish. This guide shows you how to install Ruby and Rails 5 in a Virtual Box, React JS via create-react-app and connecting the frontend and backend.

Table of Contents

Downloading Virtual Box

  • Why Virtual Box? What is it? We'll be using Ubuntu to work with our rails applications so it'll be more organized for us to be working in a virtual enviorment! You can always destroy the enviorment and reconfigure whenever you want.
  1. Download VirtualBox 5.2.22 for Mac OSX here, or Windows here
  2. Run the installer.
  3. Download Vagrant for Mac OSX here, or Windows here
  4. Let's create our first enviorment. You can run the script below to keep your rails projects on your Desktop.
cd /Desktop && mkdir rails && cd rails && vagrant init
  1. Download the OS to VirtualBox
vagrant box add ubuntu/trusty64
  1. Double check and make sure our new box is there
vagrant box list
  1. Add this script to the Vagrant File
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
end
  1. Start the vagrant server
vagrant up && vagrant ssh
  1. Direct yourself to the vagrant directory
cd /vagrant
  1. Add our Bootstrap File
mkdir new_project && cd new_project && touch bootstrap.sh
  1. Copy this script to configure our virtual enviorment
#!/usr/bin/env bash
# upgrade and update the system
echo upgrading and updating the system
sudo apt-get update
sudo apt-get -y upgrade
# install node.js for js runtime when using Rails
echo installing nodejs for ExecJS runtime and git
sudo apt-get install -y nodejs
sudo apt-get install -y git
# install RVM
echo installing RVM
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL https://get.rvm.io | bash -s stable
source /home/vagrant/.rvm/scripts/rvm
rvm requirements
# install Ruby and make 2.3.1 the default
echo installing ruby
rvm install 2.3.1
rvm use 2.3.1 --default
# install Bundler and Rails
echo installing bundler and rails
gem install bundler --no-ri --no-rdoc
gem install rails -v 4.2.7 --no-ri --no-rdoc
# install postgres and its dependencies
echo installing psql and its dependencies
sudo apt-get install -y postgresql postgresql-contrib libpq-dev
  1. Re-edit the vagrant file for our newest editions + new bootstrap file
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network "forwarded_port", guest: 3000, host: 3000, host_ip: "127.0.0.1"
config.vm.provision :shell, path: "bootstrap.sh", privileged: false
config.vm.provider "virtualbox" do |vb|
vb.customize ["modifyvm", :id, "--memory", "2048"]
vb.customize ["modifyvm", :id, "--cpus", "2"]
end
end
  1. Open a new tab in your terminal and lets test the vagrant configs
vagrant halt && vagrant up --provision
  1. Last step. whew...! Once your vagrant server is on (vagrant up and vagrant ssh!), check that Ruby and Rails was installed!
ruby -v

Downloading create-react-app

First we need Node Packet Manager if you dont already. You can download it here. Run the installer and save settings so npm is saved globally.

Let's begin!

  1. run npm install -g create-react-app and let the files download to your drive.

1a. If you are running problems with the ERR! message, try using sudo to run privileges as administrator.

  1. Let's create a test app to see if everything is running smoothly. type create-react-app my-cool-app in the command line and see if everything installs. my-cool-app will be the name of your react project.

  2. Run npm start and type Y in case there are some conflicting port configs in your local host. You should see the bottom image in your browser if everything was installed correctly!

Image and video hosting by TinyPic

Rails API 💎

Now that have our virtual enviorment ready, we can create our first ever Rails API. The new rails api command scaffolds everything we need to get up and ready for our project. Let's start our vagrant server and ssh into our project folder.

  1. Run the following: rails new my-first-api --api -T

What's going on here? The --api command tells rails that we want an API structure application instead of a standard rails structure. The -T command also tells rails that we don't want Minitest as our testing suite. You'll most likely be used to Rspec so we'll talk about that later in the guide.

  1. Enable Cross-Origin Resource Sharing (CORS) in your gem and config directory. Locate your gemfile and uncomment the following
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possiblegem'rack-cors'

Do not forget to bundle install !

Now in your config/initializers directory, you should now see a cors.rb file. Add the following to

# config/initializers/cors.rbclassApplication < Rails::Applicationconfig.middleware.insert_before0,"Rack::Cors"doallowdoorigins'*'resource'*',:headers=>:any,:methods=>[:get,:post,:patch,:options]endendend

Since this tutorial is mainly for testing and toy projects, we are allowing ALL methods from another domain. You should tailor the header and methods to your liking.

Rails API Versioning

Versioning is the process of seperating and creating new features/data/endpoints for your API. Since this is our first API, let's make our test-api v1.

  1. Run the following in your terminal
mkdir mkdir app/controllers/api && mkdir app/controllers/api/v1

If everything looks right you should see your directory identical as below.

Image and video hosting by TinyPic

Now that our versioning is complete, let's test out a model and controller to work with our new url of localhost:3000/api/v1.

  1. Let's scaffold a test model/controller and call it movies
railsgscaffoldMoviesname:stringrating:integerrailsdb:migrate

The Rails engine creates your controller in the default /controllers directory but we need to move our new controller into the api/v1 directory.

  1. You can either move it manually or the following:
mv app/controllers/movies_controller.rb app/controllers/api/v1
  1. Update the Movies Controller

Our newly generated controller does not properly inherit from the namespace api/v1 (We will update the routes later in the tutorial) so let's change our controller class from

classMoviesController < ApplicationController

TO

classApi::V1::MoviesController < ApplicationController
  1. Update the Routes Locate to your config folder and open your routes.rb file.
Rails.application.routes.drawdoresources:moviesend

If we go to localhost:3000/movies we will not call the controller. We must update our Routes to:

Rails.application.routes.drawdonamespace:apidonamespace:v1doresources:moviesendendend

which allows us to call the json data from localhost:3000/api/v1/movies

  1. Let's seed our sqlite database with some classic movies so we can practice getting data with GET requests to the API.

Copy and paste the following data to your db/seeds.rb file.

Movie.create(name: "The Nightmare Before Christmas",rating: 5)Movie.create(name: "Titanic",rating: 5)Movie.create(name: "Venom",rating: 4)Movie.create(name: "A Quiet Place",rating: 5)Movie.create(name: "Nobody's Fool",rating: 2)Movie.create(name: "Suspiria",rating: 4)Movie.create(name: "Hereditary",rating: 4)Movie.create(name: "Office Space",rating: 5)Movie.create(name: "Elf",rating: 4)Movie.create(name: "Dawn of the Planet of the Apes",rating: 3)Movie.create(name: "Secret life of Pets",rating: 4)Movie.create(name: "Overlord",rating: 3)Movie.create(name: "Wonder Woman",rating: 5)Movie.create(name: "Bohemian Rhapsody",rating: 4)Movie.create(name: "Ocean's 8",rating: 5)

Seed the DB using rails db:seed && rails db:migrate

  1. Test the API using a GET request.

Start your Rails server rails s and navigate to localhost:3000/api/v1/movies and if it is successful you should see the following JSON output:

(Optional) I'm using a pretty JSON viewer for chrome which you can download here.Image and video hosting by TinyPic

Congrats! You have successfully created a Rails API and completed your first GET request!

Downloading React into our Project

React is a component based front end framework that makes it easy to make frontend calls to our Rails API. Let's make this organized as possible and add our react directory inside our rails app.

  1. Open your terminal and create a new project inside your API.
create-react-app client

Image and video hosting by TinyPic
  1. Download Boostrap into the react directory:
npm install --save reactstrap bootstrap@4

Then open your index.js file inside the /src directory and add the following import line:

importReactfrom"react";importReactDOMfrom"react-dom";import"./index.css";importAppfrom"./App";import*asserviceWorkerfrom"./serviceWorker";// Import goes below for Bootstrapimport"bootstrap/dist/css/bootstrap.css";
  1. Let's proxy our client so we know where to get the requests from!

Open package.json from our react folder and add the following json code to your package.

"proxy": "http://127.0.0.1:3000",

Heres mine as an example!

{"name": "client","version": "0.1.0","private": true,"proxy": "http://127.0.0.1:3000","dependencies": {"bootstrap": "^4.1.3","react": "^16.6.3","react-dom": "^16.6.3","react-scripts": "2.1.1","reactstrap": "^6.5.0"},
  1. We'll make a default Component directory inside the /src folder and create our first component.
cd client/src && mkdir components && cd components && touch Button.js
  1. Open your Button.js file and lets create a sample button to activate our call function to the API.
importReact,{Component}from"react";classButtonextendsComponent{render(){return(<div><divclass="card container mt-3"><divclass="card-body"><divclass="row"><center><buttonclass="btn btn-primary">Test Call!</button></center></div></div></div></div>);}}exportdefaultButton;
  1. Start your server npm start and check if your bootstrap import works as well as the test button! If all is displaying then we are almost done. We are sooooo close!

We want our button to actually call the API now so lets create the function with the appropriate call. We want to add an onclick event to the button html like so:

<buttonclass="btn btn-primary"onClick={this.callApi}>
Test Call!
</button>

and our custom function PLUS the initial state set to null

state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};

After copying and pasting both snippets inside the Button.js file, we fetch from the url http://localhost:3000/api/v1/movies in a json format and once we return a true response we will set the response to the data variable and console log the results into the browser.

This should be the complete Button.js file below!

importReact,{Component}from"react";classButtonextendsComponent{state={results: []};callApi=async()=>{constapi_call=awaitfetch("http://localhost:3000/api/v1/movies");constdata=awaitapi_call.json();this.setState({results: data});};render(){return(<div><divclassName="card container mt-3"><divclassName="card-body"><divclassName="row"><center><buttonclassName="btn btn-primary"onClick={this.callApi}>
Test Call!
</button><br/></center><br/><br/><br/><br/><br/><pclassName="m-5">{this.state.results.map(obj=><li>{obj.name}</li>)}</p></div></div></div></div>);}}exportdefaultButton;
  1. Finally, let's open our App.js file in the /src directory to add our new Button Component to the App itself. Check below to see the example. Don't forget that we need to enclose the <Button /> in two <div></div> tags!
importReact,{Component}from'react';importlogofrom'./logo.svg';import'./App.css';importButtonfrom'./components/Button';classAppextendsComponent{render(){return(<div><Button/></div>);}}exportdefaultApp;

This should be everything we need to setup the API. Simply click our test api call button and see the magic work!

Congratulations! Our Rails API and React Client is done! If you enjoyed this API tutorial please give it a star and share it with your friends!

Rails Serializers

What are Serializers? Well Rails API's returns JSON data in full, so serializers allows us to cherry pick the exact data we want in a much organized fashion. Instead of getting every column from the returned data, we can grab which ever we allow to pass through.

Normal ModelSerializer Model
id, name, rating, director, score, actors_id, created_at, updated_atid, name, rating

We are able to tell the Rails API what to fetch rather than the frontend; making it much more simple and faster to scaffold your next project.

  1. Installation

Open your gemfile and add the serializer gem into your project. Don't forget to bundle install !

# Serializergem'active_model_serializers'

We want to create a clone of any current model we have so when we make requests in the backend, the request will read the serializer file first, then it will find the rails model/controller to finisht the request. We have a model called Movie so we'll duplicate that by running:

rails g serializer movie

You can see that a new directory was made in the app/ directory and we now have app/serializers/movie_serializer file in our project.

Let's open that file and see what we have:

classMovieSerializer < ActiveModel::Serializerattributes:idend

We have our Movie Class inheriting from the serializer class on the first line, and the returned attribute on the second. So far the default returned attribute is just an ID. Let's test this now!

1a. Turn on your rails server and go to the url localhost:3000/api/v1/movies

You should see that only the id attribute is being returned from the database.

{
id: 1
},
{
id: 2
},
{
id: 3
}

You can add any attribute to your liking to the serializer file for your next big project. But that's the end of the serializer section!

About

📱A Rails 5 API backend React JS Frontend Guide 💞

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages