Api On Rails-Preview
Api On Rails-Preview
APIs on Rails
Building REST APIs with Rails
Abraham Kuri
ii
Contents
1 Introduction 1
1.1 Conventions on this book . . . . . . . . . . . . . . . . . . . . 3
1.2 Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2.1 Development environments . . . . . . . . . . . . . . 4
1.3 Initializing the project . . . . . . . . . . . . . . . . . . . . . . 9
1.3.1 Installing Pow or Prax . . . . . . . . . . . . . . . . . 9
1.3.2 Gemfile and Bundler . . . . . . . . . . . . . . . . . . 11
1.4 Version Control . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.5 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2 The API 17
2.1 Planning the application . . . . . . . . . . . . . . . . . . . . 17
2.2 Setting the API . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.2.1 Routes, Constraints and Namespaces . . . . . . . . . 20
2.2.2 Api versioning . . . . . . . . . . . . . . . . . . . . . 24
2.2.3 Improving the versioning . . . . . . . . . . . . . . . . 25
2.3 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
iii
iv CONTENTS
4 Refactoring tests 57
4.1 Refactoring the json response . . . . . . . . . . . . . . . . . . 60
4.2 Refactoring the format param . . . . . . . . . . . . . . . . . . 62
4.3 Refactor before actions . . . . . . . . . . . . . . . . . . . . . 63
4.4 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
5 Authenticating users 67
5.1 Stateless and sign in failure . . . . . . . . . . . . . . . . . . . 68
5.1.1 Authentication token . . . . . . . . . . . . . . . . . . 68
5.1.2 Sessions controller . . . . . . . . . . . . . . . . . . . 71
5.2 Current User . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
5.3 Authenticate with token . . . . . . . . . . . . . . . . . . . . . 79
5.4 Authorize actions . . . . . . . . . . . . . . . . . . . . . . . . 81
5.5 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
6 User products 87
6.1 Product model . . . . . . . . . . . . . . . . . . . . . . . . . . 88
6.1.1 Product bare bones . . . . . . . . . . . . . . . . . . . 88
6.1.2 Product validations . . . . . . . . . . . . . . . . . . . 90
6.1.3 Product/User association . . . . . . . . . . . . . . . . 91
6.2 Products endpoints . . . . . . . . . . . . . . . . . . . . . . . 95
6.2.1 Show action for products . . . . . . . . . . . . . . . . 96
6.2.2 Products list . . . . . . . . . . . . . . . . . . . . . . . 98
6.2.3 Exploring with Sabisu . . . . . . . . . . . . . . . . . 99
6.2.4 Creating products . . . . . . . . . . . . . . . . . . . . 100
CONTENTS v
10 Optimization 179
10.1 Pagination . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
10.1.1 Products . . . . . . . . . . . . . . . . . . . . . . . . 180
10.1.2 Orders . . . . . . . . . . . . . . . . . . . . . . . . . . 185
10.1.3 Refactoring pagination . . . . . . . . . . . . . . . . . 186
10.2 Background Jobs . . . . . . . . . . . . . . . . . . . . . . . . 189
10.3 API Caching . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
10.4 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
About the author
Abraham Kuri is a Rails developer with 5 years experience. His experience
includes working as a freelancer building software products and more recently
to collaborate into the open source community. He developed Furatto a front
end framework built with Sass, Sabisu the next generation api explorer for your
Rails app and have collaborated on other projects. He is a Computer Science
graduate of ITESM and founded two companies in Mexico (Icalia Labs and
Codeando Mexico).
vii
viii ABOUT THE AUTHOR
Copyright and license
API’s on Rails: Building REST API’s with Rails. Copyright l’ 2014 by Abra-
ham Kuri. All source code in the tutorial is available jointly under the MIT
License and the Beerware License.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Abraham Kuri wrote this code. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return.
* ----------------------------------------------------------------------------
*/
ix
x COPYRIGHT AND LICENSE
Chapter 1
Introduction
Welcome to APIs on Rails a tutorial on steroids on how to buid your next
API with Rails. The goal of this book is to provide an answer on how to de-
velop a RESTful API following the best practices out there, along with my
own experience. By the time you are done with API’s on Rails you should
be able to build your own API and integrate it with any clients such as a
web browser or your next mobile app. The code generated is built on top of
Rails 4 which is the current version, for more information about this check out
http://rubyonrails.org/. The most up-to-date version of the API’s on Rails can
be found on http://apionrails.icalialabs.com; don’t forget to update your offline
version if that is the case.
The intention with this book it’s not teach just how to build an API with
Rails rather to teach you how to build scalable and maintanable API with Rails,
which means taking your current Rails knowledge to the next level when on this
approach. In this journey we are going to take, you will learn to:
1
2 CHAPTER 1. INTRODUCTION
I highly recommend you go step by step on this book, try not to skip chap-
ters, as I mention tips and interesting facts for improving your skills on each on
them. You can think yourself as the main character of a video game and with
each chapter you’ll get a higher level.
In this first chapter I will walk you through on how to setup your environ-
ment in case you don’t have it already. We’ll then create the application called
market_place_api. I’ll emphasize all my effort into teaching you all the
best practices I’ve learned along the years, so this means right after initializ-
ing(Section 1.3) the project we will start tracking it with Git (Section 1.4).
In the next chapters we will be building the application to demonstrate a
simple workflow I use on my daily basis. We’ll develop the whole application
using test driven development (TDD), getting started by explaining why you
want to build an API’s for your next project and decising wheter to use JSON
or XML as the response format. From Chapter 3 to Chapter 8 we’ll get our
hands dirty and complete the foundation for the application by building all
the necessary endpoints, securing the API access and handling authentication
through headers exchange. Finally on the last chapter (Chapter 11) we’ll add
some optimization techniques for improving the server responses.
The final application will scratch the surface of being a market place where
users will be able to place orders, upload products and more. There are plenty
of options out there to set up an online store, such as Shopify, Spree or Ma-
gento.
By the end or during the process(it really depends on your expertise), you
will get better and be able to better understand some of the bests Rails resources
out there. I also took some of the practices from these guys and brought them
to you:
• Railscasts
• CodeSchool
• Json api
1.1. CONVENTIONS ON THIS BOOK 3
I’ll be using some guidelines related to the language, what I mean by this
is:
• “Prefer” indicates that from the 2 options, the first it’s a better fit
If for any reason you encounter some errors when running a command,
rather than trying to explain every possible outcome, I’ll will recommend you
to ‘google it’, which I don’t consider a bad practice or whatsoever. But if you
feel like want to grab a beer or have troubles with the tutorial you can always
shout me tweet or email me. I’m always willing to know you guys!
• Bundler gem
for Rails development an IDE is way to much, but some other might find that
the best way to go, so if that it’s your case I recommend you go with RadRails
or RubyMine, both are well supported and comes with many integrations out
of the box.
Now for those who are more like me, I can tell you that there are a lot of
options out there which you can customize via plugins and more.
• Text editor: I personally use vim as my default editor with janus which
will add and handle many of the plugins you are probably going to use. In
case you are not a vim fan like me, there are a lot of other solutions such
as Sublime Text which is a cross-platform easy to learn and customize
(this is probably your best option), it is highly inspired by TextMate (only
available for Mac OS). A third option is to use a more recent text editor
from the guys at Github called Atom, it’s a promising text editor made
with Javascript, it is easy to extend and customize to meet your needs,
give it a try. Any of the editors I present will do the job, so I’ll let you
decide which one fits your eye.
• Terminal: If you decided to go with kaishi for setting the environment
you will notice that it sets the default shell to zsh, which I highly rec-
ommend. For the terminal, I’m not a fan of the Terminal app that comes
out of the box if you are on Mac OS, so check out iTerm2, which is a ter-
minal replacement for Mac OS. If you are on Linux you probable have a
nice terminal already, but the default should work just fine.
Browsers
When it comes to browsers I would say Chrome immediately, but some
other developers may say Firefox or even Safari. Any of those will help you
build the application you want, they come with nice inspector not just for the
dom but for network analysis and many other features you might know already.
A note on tools
All right, I understand that you may not want to include every single pack-
age that comes with kaishi, and that is fair, or maybe you already have some
tools installed, well I’ll describe you how to install the bare bones you need to
get started:
6 CHAPTER 1. INTRODUCTION
Package manager
• Mac OS: There are many options to manage how you install packages on
your Mac, such as Mac Ports or Homebrew, both are good options but I
would choose the last one, I’ve encountered less troubles when installing
software and managing it. To install brew just run the command below:
• Linux: You are all set!, it really does not matter if you are using apt,
pacman, yum as long you feel comfortable with it and know how to in-
stall packages so you can keep moving forward.
Git
We will be using Git a lot, and you should use it too not just for the purpose
of this tutorial but for every single project.
• Mac OS:
• Linux:
Ruby
There are many ways in which you can install and manage ruby, and by
now you should probably have some version installed (1.8) if you are on Mac
OS, to see which version you have, just type:
$ ruby -v
1.2. GETTING STARTED 7
Rails 4 requires you to install version 1.9 or higher, and in order to accom-
plish this I recommend you to start using Ruby Version Manager (RVM) or
rbenv, any of these will allow you to install multiple versions of ruby. I re-
cently changed from RVM to rbenv and it’s great, so any of these two options
you choose is fine. On this tutorial we’ll be using rbenv.
A note for Mac OS: if you are using Mac just keep in mind you have to have
installed the Command Line Tools for Xcode.
Mac OS:
To get started with the ruby installation, type in:
Next you have to set up the just installed version of ruby as the default one:
The rehash command is supposed to run everytime you install a new ruby
version or a gem. Seems like a lot? check out rbenv-gem-rehash brew formula
to mitigate this.
For more information about customization or other types of installation
checkout out the project documentation.
Linux:
The first steo is to setup some dependencies for Ruby:
$ cd
$ git clone git://github.com/sstephenson/rbenv.git .rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.profile
$ echo 'eval "$(rbenv init -)"' >> ~/.profile
$ exec $SHELL
On some cases if you are on a Mac OS, you will need to install some extra
libraries:
We then install the necessary gems and ignore documentation for each gem:
$ rails -v
Rails 4.0.5
1.3. INITIALIZING THE PROJECT 9
Databases
I highly recommend you install Postgresql to manage your databases, but
for simplicity we’ll be using SQlite. If you are using Mac OS you should be
ready to go, in case you are on Linux, don’t worry we have you covered:
or
As you may guess, the commands above(Listing 1.1) will generate the bare
bones of your Rails application. The next step is to add some gems we’ll be
using to build the api.
Installing Pow:
Pow only works on Mac OS, but don’t worry there is an alternative which
mimics the functionality on Linux. To install it just type in:
$ curl get.pow.cx | sh
And that’s it you are all set. You just have to symlink the application in
order to set up the Rack app.
First you go the ~/.pow directory:
$ cd ~/.pow
$ ln -s ~/workspace/market_place_api
Remember to change the user directory to the one matches yours. You can
now access the application through http://market_place_api.dev/. Your appli-
cation should be up a running by now like the one shown on Figure 1.1.
Installing Prax
For linux users only, I extracted the instructions from the official documen-
tation, so for any further documentation you should refer to the README file
on the github repository.
It is recommended that you clone the repository under the /opt directory
and then run the installer which will set the port forwarding script and NSS-
witch extension.
$ cd /opt/prax/
$ ./bin/prax install
$ cd ~/workspace/market_place_api
$ prax link
If you want to start the prax server automatically, add this line to the .profile
file:
prax start
When using prax, you have to specify the port for the URL, in this case
http://market_place_api.dev:3000
You should see the application up and running, see Figure 1.1.
#Api gems
gem 'active_model_serializers'
group :doc do
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', require: false
end
Notice that I remove the jbuilder and turbolinks gems, as we are not
really going to use them anyway.
It is a good practice also to include the ruby version used on the whole
project, this prevents dependencies to break if the code is shared among differ-
ent developers, whether if is a private or public project.
It is also important that you update the Gemfile to group the different gems
into the correct environment (Listing 1.3):
gem 'sqlite3'
end
...
This as you may recall will prevent sqlite from being installed or required
when you deploy your application to a server provider like Heroku.
Note about deployment: Due to the structure of the application we are not
going to deploy the app to any server, but we will be using Pow by Basecamp.
If you are using Linux there is a similar solution called Prax by ysbaddaden.
See Section 1.3.1
Once you have this configuration set up, it is time to run the bundle
install command to integrate the corresponding dependencies:
$ bundle install
Fetching source index for https://rubygems.org/
.
.
.
After the command finish its execution, it is time to start tracking the project
with git (Section 1.4)
Replace the last command editor("mvim -f") with the one you installed
"subl -w" for SublimeText ,"mate -w" for TextMate, or "gvim -f" for
gVim.
So it is now time to init the project with git. Remember to navigate to the
root directory of the market_place_api application:
$ git init
Initialized empty Git repository in ~/workspace/market_place_api/.git/
The next step is to ignore some files that we don’t want to track, so your
.gitignore file should look like the one shown below (Listing 1.4):
After modifiying the .gitignore file we just need to add the files and
commit the changes, the commands necessary are shown below:
1.5. CONCLUSION 15
$ git add .
$ git commit -m "Initializes the project"
then:
As we move forward with the tutorial, I’ll be using the practices I follow
on my daily basis, this includes working with branches, rebasing, squash
and some more. For now you don’t have to worry if some of these don’t sound
familiar to you, I walk you through them in time.
1.5 Conclusion
It’s been a long way through this chapter, if you reach here let me congratulate
you and be sure that from this point things will get better. If you feel like want
16 CHAPTER 1. INTRODUCTION
to share how are you doing with the tutorial, I’ll be happy to read it, a nice
example is shown below:
I just finished the first chapter of Api on Rails tutorial by @kurenn!
So let’s get our hands dirty and start typing some code!
Chapter 2
The API
In this section I’ll outline the application, by now you should have the bare
bones of the application, as shown in Section 1.3, if you did not read it I rec-
ommend you to do it.
You can clone the project until this point with:
And as a quick recap, we really just update the Gemfile to add the active_model_ser
gem, see Listing 1.2 for more information.
17
18 CHAPTER 2. THE API
Figure 2.1