Yodatra
Backend development you shall do. And yodatra you shall use.
A minimalistic framework built on top of Sinatra it is.
The power of ActiveRecord it gives you and the simplicity of a Sinatra app. And all sort of small helpers.
Instantly deploy your API
Based on your ActiveRecord models an API will be exposed very simply.
For every resource you want to expose, you will need to create a controller that inherits from the Yodatra::ModelsController
.
For example, given a User
model
class User < ActiveRecord::Base
# Your model definition
end
Creating a controller as simple as
class UsersController < Yodatra::ModelsController
# limit read_scope
def read_scope
{ only: [:id, :name] }
end
# whitelist assignable attributes
def user_params
params.permit(:name)
end
end
will expose all these routes:
GET /users
retrieves all users (attributes exposed are limited by the
read_scope
method defined in the controller)
GET /users/:id
retrieves a user (attributes exposed are limited by the
read_scope
method defined in the controller)
POST /users
creates a user (attributes assignable are limited by the
user_params
method defined in the controller as advised here http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters)
PUT /users/:id
updates a user (attributes assignable are limited by the
user_params
method defined in the controller as advised here http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters)
DELETE /users/:id
deletes a user
If your model is referenced by another model (with a has_many
, has_one
or belongs_to
relationship), nested routes are also created for you. And you don't need to worry about the references/joins, they are done automaticaly!
For example, imagine a Team
model that has many User
s
class Team < ActiveRecord::Base
has_many :users
end
the following routes will be exposed by the UsersController
controller:
GET /team/:team_id/users
GET /team/:team_id/users/:id
POST /team/:team_id/users
PUT /team/:team_id/users/:id
DESTROY /team/:team_id/users/:id
Note
You can disable any of these actions by using the ::disable class method and providing the list of actions you want to disable
class UsersController < Yodatra::ModelsController
disable :read, :update, :delete, :nested_read_all, :nested_delete
end
Extra
You can enable a special "search" action by using the ::enable_search_on class method
class UsersController < Yodatra::ModelsController
enable_search_on :name
end
What it also provides for free
-
Logger: Logs inside
<your_project>/log
in an environment named fileenv.err.log
for all errors andenv.log
only for access logs. -
Boot: loads automaticaly all
<your_project>/app/models/**/*.rb
files and<your_project>/app/controllers/**/*.rb
files. Establish a connection with a database by reading the<your_project>/config/database.yml
file
For that create a sinatra app that inherits from Yodatra::Base
instead of Sinatra::Base
.
Other useful modules
- Throttling: To fight against the dark side, an API throttling you will need. Example: allow only 10 requests/minute per IP:
use Yodatra::Throttle, {:redis_conf => {}, :rpm => 10}
warning: this module requires redis
-
ApiFormatter: this middleware will help you to format all your replies. Example: wrap all you replies within a
{data: <...>}
object:
use Yodatra::ApiFormatter do |status, headers, response|
body = response.empty? ? '' : response.first
response = [{:data => body}]
[status, headers, response]
end