Using Rails API With React
Tags: rails, api, ruby, react
Published: 2019-12-03 21:06:38

Maybe you started using the traditional MVC (Model, View, Controller) outline for your rails apps. But now that you're using a frontend framework like React, you simply want to store your data and implement most of your logic in your backend. Great.

So what does that mean? And how do you do that?

You can use a Rails API. This simply means that you can render a bunch of JSON files that can communicate with your frontend.

For example, say you want to display a page with all of your books. You would typically have something like this in your controller.rb:

```ruby
class BooksController < ApplicationController
   def index
     @books = Book.all
   end
end


```

and something like this in your index.html.erb:

```ruby
<% @books.each do |book| do %>
     <%= book.title %>
<% end %>

```

Now that you're using React, you don't need to use views anymore. React is your new "views."


Let's go back to your controller. Now, we can render a JSON file with all of your books and their attributes (you will see why you need this in just a minute):

```ruby
class BooksController < ApplicationController
   def index
     books = Book.all
     render json: books
   end
end


```

Don't forget your routes:


```ruby
  resources :books

```

If you run our server ("rails s" in your terminal), you will see a JSON file that looks like this:


```json
{
    "books": [
              {"title": "Harry Potter",
               "author": "JK Rowling"
              },

              {"title": "The Cat in the Hat",
               "author": "Dr. Seuss"
              }
             [
}

```

Now you can go to your frontend, and fetch this API data to use how you'd like. For example:

```javascript
fetch('http://localhost:3000/books', {
        headers: {
            'Content-Type': 'application/json',
            Accept: 'application/json',
            Authorization: token
        }
    })
      .then(res => res.json())
      .then(data => this.setState({
             allBooks: data
           })
      )
    };
```

If you console.log(allBooks), you should see that you now have access to all of that data in your frontend.

What's really awesome about this is that you can handle most of the heavy logic required to showcase your data in your backend and then simply fetch the data when necessary.

You can even set up different urls to hold specific data by using params in your controller. 

```ruby
  def index
    if params[:release_month]
      books = Book.by_release_month(params[:release_month])
      render json: books
    else
      books = Book.all
      render json: BookSerializer.new(books)
    end
  end
```

This is the ".by_release_month" method we used in our Book model:

```ruby
class Book < ApplicationRecord
  belongs_to :author

  def self.by_release_month(release_month)
    books = Books.filter{ |book| 
      release_month == Date::MONTHNAMES[Date.today.month]
    }
  end

end
```

This is how we can fetch these books with the new params in React:

```javascript
fetch('http://localhost:3000/books?release_month={month}')
    .then(res => res.json())
    .then(data => { 
      // Do what you want
     })
```