fit-api
Lightweight framework for building JSON API's
Introduction
fit-api is a 400 line dependency library based on Rack and inspired by Rails & Sinatra. The goal of this library is to provide simplicity when developing an API with ruby.
Installation
Install the latest version from RubyGems
$ gem install fit_api
Table of Contents
Usage
This is a basic example showing how it works... you can check the demo app from this repository: fit-api-demo
my_app.rb
require 'fit_api'
require_relative 'routes'
require_relative 'app_controller'
Rack::Handler::WEBrick.run FitApi::App.new
routes.rb
FitApi::Router.define do
get '/:name', to: 'app#show'
root to: 'app#index'
end
app_controller.rb
class AppController < FitApi::Controller
def index
json({ message: 'Hello world' })
end
def show
json({ message: "Welcome #{params.name}" })
end
end
ruby my_app.rb
Router
It recognizes URLs and invoke the controller's action... the DSL is pretty similar to Rails (obviously not to so powerful):
HTTP methods:
get '/test/:name', to: 'app#test_show'
post '/test', to: 'app#test_post'
put '/test', to: 'app#test_put'
delete '/test/:id', to: 'app#test_delete'
Resources
Nested:
resources :users do
resource :avatar do
get :comments
post :add_comment
end
end
Endpoints for users:
Method | Path | Controller & action |
---|---|---|
GET | /users | users#index |
GET | /users/:id | users#show |
POST | /users | users#create |
PATCH | /users/:id | users#update |
DELETE | /users/:id | users#destroy |
Endpoints for avatar:
Method | Path | Controller & action |
---|---|---|
GET | /users/:user_id/avatar | avatar#show |
POST | /users/:user_id/avatar | avatar#create |
PATCH | /users/:user_id/avatar | avatar#update |
DELETE | /users/:user_id/avatar | avatar#destroy |
GET | /users/:user_id/avatar/comments | avatar#comments |
POST | /users/:user_id/avatar/add_comment | avatar#add_comment |
Member & Collection:
resources :contacts, only: %i(index) do
member do
post :add_activity
end
collection do
get :search
end
end
Method | Path | Controller & action |
---|---|---|
GET | /contacts | contacts#index |
GET | /contacts/search | contacts#search |
POST | /contacts/:id/add_activity | contacts#add_activity |
Namespace
Only for paths
namespace :test do
get :hello_world
post :hello_world, action: :post_hello_world
end
Method | Path | Controller & action |
---|---|---|
GET | /test/hello_world | test#hello_world |
POST | /test/hello_world | test#post_hello_world |
namespace '/hello/world', controller: :test do
get :test
end
Method | Path | Controller & action |
---|---|---|
GET | /test/world/test | test#test |
Controller
controller :app do
get :another_action
end
Method | Path | Controller & action |
---|---|---|
GET | /another_action | app#another_action |
Root
root to: 'app#index'
Method | Path | Controller & action |
---|---|---|
GET | / | app#index |
Customize error 404 message
not_found 'app#error_404'
Controllers
The library provides one father class FitApi::Controller
that should be inherited from your controllers.
One limitation is the class name of your controller must end with "Controller", i.e: AppController, UsersController...
class AppController < FitApi::Controller
def index
json 'hello world'
end
def process_post
json params
end
end
You have the method #json
available, basically, it sets the Response body.
Request
You can access the Request object like this: request
Params
Assuming the following requests:
GET /users/:id?name=Berna&age=28&height=180
params.id # 1
params.name # "Berna"
params[:age] # 28
params['height'] # 180
POST /test
With Params:
curl -i -X POST -d 'user[name]=Berna&user[age]=28' http://server:1337/test
With JSON:
curl -i -X POST -H "Content-Type: application/json" -d '{ "user": { "name": "Berna", "age": 28 } }' http://server:1337/test
Then we have the following data in our params
object:
params.user # > Params
params.user.name # "Berna"
params[:user][:age] # 28
Request Headers
request.headers['Authorization']
Response Headers
headers['Header-Key'] = 'Header Value'
Callbacks
before_action *actions
after_action *actions, only: %i(index show)
Rack Middlewares
You can set up any rack middleware you want, i.e:
config.ru
require 'fit_api'
use Rack::CommonLogger, Logger.new('log/app.log')
run FitApi::App.new
TODO:
- [ ] Implement tests
- [ ] Allow websockets ->
FitApi::Controller#stream
Any contribution would be appreciated =)