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
endChoose 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
endUser 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
endGet 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_titleResend
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
- 141
 
   
   
  