Been working on a side project with a friend and we were at the point where we needed to build an API for the code we had written. The idea was to build an API which can be accessed by our customers with an API key.
After some research, I found couple of gems that make it easy to do this. Rocket Pants and Versionist. In order to reduce the dependencies, I decided to build it myself with the help of RailsCasts.
Creating the API.
We will start off by creating the routes for it.
1 2 3 4 5 6 7 |
|
This block of code gives us the following route:
1
|
|
Now in order to create the controller, since they are namespaced under api and the version number you must put the controller inside the two modules.
1 2 3 4 5 6 7 8 9 10 11 |
|
Now doing the following should give you a list of YouTube results in a JSON format.
1
|
|
This setup gives us the ability to easily add new versions of the API while maintaining backwards compatibility. The only thing is that the API is not secure.
Securing the API.
There are a few ways you can do this. Instead of doing it with OAuth I just created an access token given to each application created. The access token is created using a SecureRandom.hex string.
1 2 3 4 5 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
The way I set this up is that a user can have many applications, and each application belongs to a user. Before an application is created there is a unique key which is generated restricing access to the API. There are other columns you can add to the model if needed such as permissions, expires_at etc.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Updating the controller in order to send an unauthorized response if the access key is invalid. Now in order to make a request the user has to send in the right access_token in the parameters. Also make sure to not make the access_token field accessible using attr_accessible or in rails 4 you can do the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Instead of directly passing in the params[:application] we pass the build method a method itself. This private method makes sure to only permit the application name.
Since the output of my controllers were already in JSON there was no need for RABL. Also for those looking for something lightweight can have a look at Rails-API. This is enough to get you started if you any questions leave comments and I shall address them.