Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Simple Task List application APIs

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for Venky Venky
January 18, 2020

Simple Task List application APIs

Presentation to help the steps involved in creating the list of APIs needed for a Trello like task list application

Avatar for Venky

Venky

January 18, 2020
Tweet

Other Decks in Technology

Transcript

  1. Setup instructions • Install the docker desktop • Clone the

    git repository • docker-compose build • docker-compose up • docker-compose run web rake db:create • Access the rails application at http://localhost:4000 • docker exec -it rails_web_1 bash
  2. Data Model Dashboards Title String User_id Integer Lists Title String

    Sort_order Integer dashboard_i d Integer Cards Title String Description Text Sort_order Integer list_id Integer Assignee_id Integer Users Email String
  3. List of APIs to build • GET api/v1/users • GET

    /api/v1/dashboards • GET /api/v1/dashboards/1 • PUT /api/v1/dashboards/1 • POST api/v1/dashboards/1/lists • PUT api/v1/dashboards/1/lists/1 • GET api/v1/dashboards/1/lists/1/cards • POST api/v1/dashboards/1/lists/1/cards • PUT api/v1/dashboards/1/lists/1/cards/5 • POST api/v1/dashboards/1/lists/1/cards/4/move
  4. User Model • We have already included the devise gem

    for User Management • Has the ability to login / sign up.
  5. Dashboard Model • Generate the dashboard model using the following

    command • rails g model Dashboard title:string user:references • Update the Dashboard Model to create the associations • belongs_to :user • has_many :lists, ->{ order(sort_order: :asc) }
  6. List Model • Generate the list model using the following

    command • rails g model List title:string sort_order:integer dashboard:references • Update the List Model to create the associations • belongs_to :dashboard • has_many :cards, ->{ order(sort_order: :asc) }
  7. Card Model • Generate the card model using the following

    command • rails g model Card title:string description:text sort_order:integer list:references • To add the assignee as the user, edit the migration file with the following content • t.references :assignee, foreign_key: { to_table: :users } • Update the Card Model to create the associations • belongs_to :list • belongs_to :assignee, class_name: "User", optional: true
  8. Update the DB • Run db:migrate to update the Database

    • In case you run into issues, you can run db:rollback to undo the most recent migration
  9. Update the routes namespace :api do namespace :v1 do resources

    :users, only: [:index] resources :dashboards, only: [:index, :show, :create, :update] do resources :lists, only: [:create, :update] do resources :cards, only: [:index, :show, :create, :update] do member do put 'move’ end end end end end end
  10. User Serializer • Run the command • rails g serializer

    User • Update the generated class class UserSerializer < ActiveModel::Serializer attributes :id, :email end
  11. BasicDashboard Serializer • Run the command • rails g serializer

    BasicDashboard • Update the generated class class BasicDashboardSerializer < ActiveModel::Serializer attributes :id, :title end
  12. Dashboard Serializer • Run the command • rails g serializer

    Dashboard • Update the generated class class DashboardSerializer < ActiveModel::Serializer attributes :id, :title has_many :lists, serializer: ListSerializer end
  13. List Serializer • Run the command • rails g serializer

    List • Update the generated class class ListSerializer < ActiveModel::Serializer attributes :id, :title, :sort_order has_many :cards, serializer: CardSerializer end
  14. Card Serializer • Run the command • rails g serializer

    Card • Update the generated class class CardSerializer < ActiveModel::Serializer attributes :id, :title, :description, :sort_order, :assignee def assignee object.assignee&.email end end
  15. Dashboards Controller class Api::V1::DashboardsController < ApplicationController skip_before_action :verify_authenticity_token def index

    dashboards = Dashboard.includes(lists: :cards).all render json: dashboards, each_serializer: BasicDashboardSerializer end def show dashboard = Dashboard.includes(lists: :cards).find(params[:id]) if dashboard render json: dashboard, include: '**', format: :json else render json: { error: "Dashboard with id #{params[:id]} Not found" }, status: :not_found end end def create dashboard = Dashboard.new(dashboard_params) if dashboard.save render json: dashboard, serializer: BasicDashboardSerializer, status: :created else render json: { error: dashboard.errors.full_messages }, status: :unprocessable_entity end end def update dashboard = Dashboard.find(params[:id]) if dashboard.update(dashboard_params) render json: dashboard, serializer: BasicDashboardSerializer, status: :ok else render json: { error: dashboard.errors.full_messages }, status: :unprocessable_entity end end private def dashboard_params params.require(:dashboard).permit(:title, :user_id) end end
  16. Lists Controller class Api::V1::ListsController < ApplicationController skip_before_action :verify_authenticity_token before_action :dashboard,

    only:[:create, :update] def create list = dashboard.lists.build(list_params) if list.save render json: list, status: :created else render json: { error: list.errors.full_messages }, status: :unprocessable_entity end end def update list = List.find(params[:id]) if list.update(list_params) render json: list, status: :created else render json: { error: list.errors.full_messages }, status: :unprocessable_entity end end private def dashboard @dashboard ||= Dashboard.find(params[:dashboard_id]) end def list_params params.require(:list).permit(:title, :sort_order, :dashboard_id) end end
  17. Cards Controller class Api::V1::CardsController < ApplicationController skip_before_action :verify_authenticity_token before_action :list,

    only:[:index, :create, :update] def index cards = list.cards render json: cards, each_serializer: CardSerializer end def show card = Card.find_by_id(params[:id]) if card render json: card else render json: { error: "Card with id #{params[:id]} Not found" }, status: :not_found end end def create card = list.cards.build(card_params) if card.save render json: card, status: :created else render json: { error: card.errors.full_messages }, status: :unprocessable_entity end end
  18. Cards Controller (contd) def update card = Card.find(params[:id]) if card.update(card_params)

    render json: card, status: :ok else render json: { error: card.errors.full_messages }, status: :unprocessable_entity end end def move card = Card.find(params[:id]) MoveCard.new(card: card, direction: params.fetch(:direction, 'up')).call render json: list.cards, each_serializer: CardSerializer end private def dashboard @dashboard ||= Dashboard.find(params[:dashboard_id]) end def list @list ||= dashboard.lists.find(params[:list_id]) end def card_params params.require(:card).permit(:title, :description, :sort_order, :assignee_id, :list_id, :dashboard_id) end end