How to REST

How to Series
REST, branch, Rails, Start, Single Sign On, Deploy, Continuous Deployment, Report Issue, ...
DHH: The missing part


AHA moment
Problems
- Lack of constraints
- When should I introduce new controller?
- Where should I put new action?
- How much action should do?
Representational State Transfer
REST systems interface with external systems as web resources identified by Uniform Resource Identifiers (URIs)
What is Resource?
Database table
Never ever even if looks similar
{
"id": 1,
"projects": [
{
"id": 13,
"name": "Projekt"
},
{
"id": 15,
"name": "Inny projekt"
}
],
"birthdate": "19.03.2003",
"name": "Guess Who"
}GraphQL vs REST
Premature optimization
You can nest resources
but don't from day 1
Fun fact
REST is easy
Use only basic actions
- index
- show
- update
- new
- create
- destroy
- edit
New action
==
Think about resources
Examples
Current user
class CurrentUsersController < ApplicationController
def show
# ...
end
end
# or
module Users
class CurrentsController < ApplicationController
def show
# ...
end
end
end
Choose picture
module Api
module V1
class PicturesController < Api::V1::BaseController
def choose
# ...
end
end
end
end
Choose picture
module Api
module V1
class PicturesController < Api::V1::BaseController
class Selected < Api::V1::BaseController
def create
# ...
end
end
end
end
end
User groups
class API::V3::Main::Groups < Grape::API
include API::V3::Main::Defaults
include Grape::Kaminari
resource :groups do
paginate
params do
requires :user_id, type: Integer, desc: "User ID"
end
get "user/:user_id" do
# ...
end
end
end
User groups
class API::V3::Main::Users::Groups < Grape::API
include API::V3::Main::Defaults
include Grape::Kaminari
resource :users do
params do
requires :id, type: Integer, desc: "User ID"
end
namespace ":id/groups" do
get "/" do
# like index action
end
end
end
end
Get title
module API
module V1
class Findings < Grape::API
include API::V1::Defaults
include Grape::Kaminari
resources :findings do
params do
requires :link, type: String
end
get "get_title" do
# ...
end
end
end
end
end
Get title
Title # resource
show # get_title
Resend
module Api
class CrewMembersController < ApplicationController
before_action :doorkeeper_authorize!
before_action :authenticate!
before_action :require_company
api :POST, '/crew_members/:id/resend', 'Resend a crew invitation email'
param :id, :uuid, required: true
def resend
# ...
end
end
end
Resend
Invitation # resource
create # create (and probably send) new one
# alternative e.g. for different logic
Reminder, Reinvitation, ... ?
Why?
- Less confusion
- Improve domain understanding
- Simpler code
Resource?
(...) information that can be named (...)
A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time.
Questions?
http://jeromedalbert.com/how-dhh-organizes-his-rails-controllers/
https://www.thoughtworks.com/insights/blog/rest-api-design-resource-modeling
http://www.restapitutorial.com/lessons/restfulresourcenaming.html
How to REST
By Jan Dudulski
How to REST
- 149