How to Build an eCommerce API With Ruby on Rails Part 1

This article was prepared by a guest contributor to ProgrammableWeb. The opinions expressed in this article are the author's own and do not necessarily reflect the view of ProgrammableWeb or its editorial staff.

Have you ever bought anything online? Millions of people do it around the globe every day. e-commerce is an essential part of business for many retailers and it continues to gain more and more supporters.

It is not only the way of buying things but of selling them as well. One cannot even count how many online-shops there are on the Internet. Some of them are very poorly made, but you can also see eye-catching ones. Guess which ones are more likely to attract a new customer?

E-commerсe sites have no geographical limits so the number of people who would like to do this kind of business is constantly growing.

Our developers work with Ruby on Rails to provide back-end solutions for projects. It is not easy to “cook” up a project like this, especially for those without much experience. But don’t worry, we have prepared a detailed “recipe” for beginners on how to create an API for an e-commerce website. Just follow our detailed instructions and you will succeed.

Today we will present the first part of our “e-commerce API recipe” that deals with creating products. It is going to be very informative so get ready and start the “development cooking”.

1. First of all, you need to install Ruby 2.2.3 and Ruby on Rails 4.2.4. You can read about the installation process here.

2. Create a new app and name it “Shop” for example. Write the command in the console to do that:

Thus, when we create controllers for our online-shop API we will be able to redefine private methods initialize_resource, build_resource, resource. This will help us to keep the controllers lightweight.

5. It is the right time to add something every shop needs - the products. Create the model “Product”, that will contain such fields for example: name, price, description. Let’s type the command in the console:

This command will generate the model product.rb in the folder app/models/ with the fields name(type string), price(type integer), description(type text) and the migration to the database db/migrate/(timestamp)_create_products.rb. The file where we will write tests for the model spec/models/product_spec.rb. will be generated too.
Then write the command in the console to create a database:

rake db:create

After that write the command to conduct the created migration to the database:

rake db:migrate

The next step is to create an API controller ProductsController where we will process requests to API of the products. Let’s start with writing tests for the controller. Create the file spec/controllers/api/products_controller_spec.rb and add the following code:

Having done this we can call methods resource and collection directly from views. No need to write action methods index and show. They are kept in the ActionController::Base from which all other controllers are inherited. They render templates with their names by default and this is exactly what we need.

Now we have to create templates and this is where the most interesting part begins. All the templates (views) will be the same, even when we add a shopping cart and orders. They will look like those for the products. That is why we need to learn about the inheritance of views in Ruby on Rails.

All of them are inherited from the application, which means in our case that Ruby on Rails will look for templates in the directory app/views/application if it doesn’t find them in the directory app/views/api/products. If it doesn’t find them in the latter one as well, you will see an error.

So let’s place the templates in the views/application directory. Create two files index.json.erb and show.json.erb. They should be in the json format because the API of the shop will transfer data in it. Add this code to index.json.erb:

<%= sanitize collection.to_json %>

And to show.json.erb:

<%= sanitize resource.to_json %>

Done. Let’s check the performance of the newly written API for the products. Launch the tests first and make sure they have run smoothly, if not - you have done something wrong.

Now we have to check the API performance with the help of the curl command in the console. Let’s add a few products to the database. Run the console command rails console and write, for example:

This code will enter two products in the database. Let’s make a request to the API with the curl command (don’t forget to launch a local server in the console with the rails server command). Write the following command in the console:

Great! The products API works fine but it displays unnecessary information such as time when the product was created (created_at) or when it was updated (updated_at).

Let’s think how we can change it without transferring the parameter (only: [:id, :name, :price, :description]) to the to_json method. We should keep in mind that all templates are the same for the whole app and there will be no such fields in another model. So what should we do? Connect the gem 'draper'. You can read about it here: https://github.com/drapergem/draper. Let’s create a new decorator app/decorators/product_decorator.rb and write the code there:

You could probably ask why the method is named as_json if we call to_json in a template. Everything is very simple if you take a closer look at how the to_json method works in the original code: as_json is called within it. If you redefine this method with the necessary hash you will get the data needed. Don’t forget to call the decorate method in templates:

Inindex.json.erb:

<%= sanitize collection.decorate.to_json %>

Inshow.json.erb:

<%= sanitize resource.decorate.to_json %>

You should also remember to write tests for the decorator in the file spec/decorators/product_decorator.rb.

Check if the tests have run properly and make requests again with the curl command (don’t forget to restart the server as we have just added new files to the app). You should see the data you need on the screen. What if a request to show action will be with an id that does not exist in the database? Then type the following in the code line in theapp/controllers/api/products_controller.rb file:

@product ||= Product.find params[:id]

The find method will raise ActiveRecord::RecordNotFound exception and it will render the 404 error. To display this error in the json format add it to the ApplicationController that will handle this exception and render the exception.json.erb. template.