Overview
Instant-API automatically creates a REST API from a Rails project
Configuration
Instant-API works with Rails (it has been tested with Rails 4.0)
Add the gem to your Gemfile
gem 'instant-api'
Create an initializer: config/initializers/instant_api.rb
require 'instant_api'
InstantApi::Controller::Routes.new.build_controllers
Example
Let's say, you have these models
class Movie < ActiveRecord::Base
has_and_belongs_to_many :countries
end
class Country < ActiveRecord::Base
has_and_belongs_to_many :movies
end
And you want to access these though a Rest API, for instanace, your config/routes.rb
YourApp::Application.routes.draw do
resources :countries do
resources :movies, only: [:index, :show]
end
end
The routes generated are
Prefix Verb URI Pattern Controller#Action
country_movies GET /countries/:country_id/movies(.:format) movies#index
country_movie GET /countries/:country_id/movies/:id(.:format) movies#show
countries GET /countries(.:format) countries#index
POST /countries(.:format) countries#create
new_country GET /countries/new(.:format) countries#new
edit_country GET /countries/:id/edit(.:format) countries#edit
country GET /countries/:id(.:format) countries#show
PATCH /countries/:id(.:format) countries#update
PUT /countries/:id(.:format) countries#update
DELETE /countries/:id(.:format) countries#destroy
Start your app and then you can make the following calls:
Create
> curl -X POST -d "country[name]=Japón;country[english_name]=Japan" http://localhost:3000/countries { "id": 87, "name": "Japón", "created_at": "2014-08-03T15:09:35.611Z", "updated_at": "2014-08-03T15:09:35.611Z", "english_name": "Japan" }
Index, pagination paremeters: page, per_page
> curl -s -X GET http://localhost:3000/countries?page=2&per_page=4 { "collection": [ { "id": 5, "name": "Netherlands", "created_at": "2010-09-16T23:46:07.000Z", "updated_at": "2013-01-28T17:32:01.000Z", "english_name": "Netherlands" }, { "id": 6, "name": "Germany", "created_at": "2010-10-21T16:53:52.000Z", "updated_at": "2013-01-28T17:29:12.000Z", "english_name": "Germany" }, { "id": 7, "name": "New Zealand", "created_at": "2010-10-21T16:55:30.000Z", "updated_at": "2013-01-28T17:32:01.000Z", "english_name": "New Zealand" }, { "id": 8, "name": "Japan", "created_at": "2010-10-21T16:59:02.000Z", "updated_at": "2013-01-28T17:32:00.000Z", "english_name": "Japan" } ], "pagination": { "count": 84, "page": 2, "per_page": 4 } } ```
Show
> curl -s -X GET http://localhost:3000/countries/5 { "id": 5, "name": "Netherlands", "created_at": "2010-09-16T23:46:07.000Z", "updated_at": "2013-01-28T17:32:01.000Z", "english_name": "Netherlands" }
Delete
> curl -s -X DELETE http://localhost:3000/countries/87
Update
> curl -s -X PUT -d "country[name]=Holanda" http://localhost:3000/countries/5 { "id": 5, "name": "Holanda", "created_at": "2010-09-16T23:46:07.000Z", "updated_at": "2014-08-03T16:18:03.215Z", "english_name": "Netherlands" }
New
> curl -s -X GET http://localhost:3000/countries/new
Edit
> curl -s -X GET http://localhost:3000/countries/3/edit { "id": 3, "name": "United States", "created_at": "2010-09-16T23:45:48.000Z", "updated_at": "2013-01-28T17:32:00.000Z", "english_name": "United States" }
All these methods works at any level:
> curl -s -X GET http://localhost:3000/countries/1/movies?page=2&per_page=3
{
"collection": [
{
"id": 202,
"title": "Good Night. And Good Luck",
"original_title": "Good Night. And Good Luck",
"year": 2005,
"duration": 90,
},
{
"id": 207,
"title": "L'amant",
"original_title": "L'amant",
"year": 1992,
"duration": 115,
},
{
"id": 239,
"title": "Tess",
"original_title": "Tess",
"year": 1979,
"duration": 170,
}
],
"pagination": { "count": 64, "page": 2, "per_page": 3 }
}
> curl -s -X GET http://localhost:3000/countries/1/movies/202
{
"id": 202,
"title": "Good Night. And Good Luck",
"original_title": "Good Night. And Good Luck",
"year": 2005,
"duration": 90
}
Errors
If there's any error creating or updating, it will be return with a 422 HTTP error
> curl -s -X POST -d "name=Japan" http://localhost:3000/countries
{ "errors": [["name", ["has already been taken"]]] }
> curl -s -X PUT -d "country[name]=Holanda" http://localhost:3000/countries/6
{ "errors": [["name", ["has already been taken"]]] }
If we ask for a resource that doesn't exists, a 404 HTTP error will be return
> curl -s -X GET http://localhost:3000/countries/666
{ "errors": { "field": "id", "message": "Couldn't find Country with id=666" } }
TODO
- Integration with a authentication mechanism, API only available to authenticated users
- Implementation of a cache
- Response json configuration