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
endCreating 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
endwill expose all these routes:
GET /users
retrieves all users (attributes exposed are limited by the
read_scopemethod defined in the controller)
GET /users/:id
retrieves a user (attributes exposed are limited by the
read_scopemethod defined in the controller)
POST /users
creates a user (attributes assignable are limited by the
user_paramsmethod 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_paramsmethod 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 Users
class Team < ActiveRecord::Base
has_many :users
endthe 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
endExtra
You can enable a special "search" action by using the ::enable_search_on class method
class UsersController < Yodatra::ModelsController
enable_search_on :name
endWhat it also provides for free
-
Logger: Logs inside
<your_project>/login an environment named fileenv.err.logfor all errors andenv.logonly for access logs. -
Boot: loads automaticaly all
<your_project>/app/models/**/*.rbfiles and<your_project>/app/controllers/**/*.rbfiles. Establish a connection with a database by reading the<your_project>/config/database.ymlfile
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