fit-api
Lightweight framework for building JSON API"s
Introduction
fit-api is a library based on Rack and inspired by Rails & Sinatra.
The goal of this gem 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
api.rb
# optional:
FitApi::Router.auto_load_path "controllers"
FitApi::Router.define do
get "/:name", to: "app#show"
root to: "app#index"
end
controllers/app_controllers.rb
class AppController < FitApi::Controller
def index
json(message: "Hello world")
end
def show
if found
json(message: "Welcome #{params.name}")
else
json(404, error: "not found")
end
end
end
rackup
Router
It recognizes URLs and invoke the controller"s action... the DSL is pretty similar to Rails (obviously not 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
You can pass the following options: only, except, controller
**Nested:**
```ruby
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: :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 | /hello/world/test | test#test |
Controller
controller :app do
get :another_action
get "/welcome", action: "hello_world"
end
Method | Path | Controller & action |
---|---|---|
GET | /another_action | app#another_action |
GET | /welcome | app#hello_world |
Root
root to: "app#index"
Method | Path | Controller & action |
---|---|---|
GET | / | app#index |
Customize error 404 message
not_found to: "app#error_404"
Controllers
The library provides one class FitApi::Controller
which 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 create
json 201, resource
end
end
Default status code: 200
Request
You can access the Request object like this:
request
Halt
You can exit the current action throwing an exception... the default status code is 400
halt
halt 500
halt 404, "Not found"
halt "Error message"
Params
GET /users
curl -i http://localhost:1337/users/:id?name=Berna&level=1&xp=70
params.id # 1
params.name # "Berna"
params[:level] # 1
params["xp"] # 70
POST with params:
curl -i -X POST -d "user[name]=Berna&user[level]=1" http://localhost:1337/users
POST with JSON:
curl -i -X POST -H "Content-Type: application/json" -d "{ "user": { "name": "Berna", "xp": 50 } }" http://localhost:1337/users
Result:
params.user.name # "Berna"
params[:user][:xp] # 50
#permit
params.user.permit(:name, :level, :xp)
#except
params.user.except(:height)
Request Headers
request.headers["Authorization"]
Response Headers
headers["Header-Name"] = "Header Value"
Callbacks
before_action *actions, only: %i(index show)
after_action *actions, except: :destroy
TODO:
- [ ] Implement tests
- [ ] Allow websockets ->
FitApi::Controller#stream
Any contribution would be appreciated =)