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

Simple Task List application APIs

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

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