{"id":19055788,"url":"https://github.com/taskrabbit/playbook","last_synced_at":"2025-06-20T10:39:25.063Z","repository":{"id":5327701,"uuid":"6511190","full_name":"taskrabbit/playbook","owner":"taskrabbit","description":"Api Groundwork: Versioning, Routing, Adapter Pattern, and API Standards","archived":false,"fork":false,"pushed_at":"2014-04-15T20:20:15.000Z","size":486,"stargazers_count":12,"open_issues_count":1,"forks_count":6,"subscribers_count":44,"default_branch":"master","last_synced_at":"2025-04-24T04:33:02.816Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"kevinzhow/PNChart","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/taskrabbit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-11-02T19:13:45.000Z","updated_at":"2020-04-05T06:45:53.000Z","dependencies_parsed_at":"2022-09-19T04:32:25.176Z","dependency_job_id":null,"html_url":"https://github.com/taskrabbit/playbook","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/taskrabbit/playbook","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taskrabbit%2Fplaybook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taskrabbit%2Fplaybook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taskrabbit%2Fplaybook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taskrabbit%2Fplaybook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/taskrabbit","download_url":"https://codeload.github.com/taskrabbit/playbook/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/taskrabbit%2Fplaybook/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260927829,"owners_count":23084101,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T23:47:01.864Z","updated_at":"2025-06-20T10:39:20.050Z","avatar_url":"https://github.com/taskrabbit.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Playbook - The Underpinnings to Your Rails API\n\nPlaybook provides your rails application with a simple way to create a customized, clean, and fast api. It lays out the groundwork for versioning, deprecation, rendering, reusability, authorization, and authentication. This README will show each major section of playbook with an example and an explanation of the code.\n\n\n#### Routing\n\nPlaybook provides you with simple way of defining versioned routes. By extending your router with the `Playbook::Router` module you are given a `versions` method. The `versions` method allows you to pass in as many float, integer, or string versions as you'd like. Your routes will be drawn explicitly for each of those versions. Regular expressions and conditions are not used.\n\n```ruby\n# routes.rb\nextend ::Playbook::Router\n\nnamespace :api do\n  versions(1.0, 2.0) do\n    \n    resources :cities, :only =\u003e [:index, :show] do\n      member do\n        post :express_interest\n      end\n    end\n  \n  end\nend\n```\n\n#### Controllers\n\nYou are provided with a `Playbook::BaseController` if you'd like to get things done quickly. If you're more interested in what's going on, check out the modules included into the `Playbook::BaseController`, specifically:\n\n  * Playbook::Controller\n  * Playbook::Authorization\n  * Playbook::Authentication\n  * Playbook::ApiStandards\n\n\n```ruby\n# app/api/controllers/api/v1/cities_controller.rb\nclass Api::V1::CitiesController \u003c ::Playbook::BaseController\n  \n  forward_to_adapter :express_interest, :render =\u003e '/api/v1/cities/show', :status =\u003e 201\n  forward_to_adapter :show,             :render =\u003e '/api/v1/cities/show'\n  forward_to_adapter :index,            :render =\u003e '/api/v2/cities/index'\n\n  require_auth :express_interest\nend\n```\n\n\n```ruby\n# app/api/adapters/api/v1/city_adapter.rb\nclass Api::V1::CityAdapter \u003c ::Playbook::Adapter\n  \n  require_params :id, :on =\u003e [:show, :express_interest]\n  whitelist :page,    :on =\u003e :index\n\n  def show\n    success(:city =\u003e city)\n  end\n\n  def index\n    cities = Cities.page(params[:page] || 1).per(20)\n    success(:cities =\u003e cities)\n  end\n\n  def express_interest\n    interest = CityInterest.new(:city =\u003e city, :user =\u003e current_user)\n    failure(interest) unless interest.save\n    \n    success(:city =\u003e city)\n  end\n\n  protected\n\n  def city\n    @city ||= City.find(params[:city_id] || params[:id])\n  end\n\nend\n```\n\n\n```ruby\n# app/api/views/v1/cities/_show.json.jbuilder\njson.extract! city, :id, :name, :lat, :lng, :created_at\n```\n\n\n```ruby\n# app/api/views/v1/cities/index.json.jbuilder\njson.collection!(@cities, :partial =\u003e '/api/v1/cities/show', :as =\u003e :city)\n```\n\n\n```ruby\n# app/api/views/v1/cities/show.json.jbuilder\njson.partial! '/api/v1/cities/show', :city =\u003e @city\n```\n\n\n```\nGET /api/v1/cities.json?page=2\n```\n\n\n```js\n{\n  request : {\n    path : '/api/v1/cities.json',\n    server_time : 1335039034,\n    api_version : '1.0',\n    computation_time : 30,\n    current_user_id : null,\n    params : {\n      page : 2\n    }\n\n  },\n  response : {\n    page : 2,\n    total_items : 35,\n    total_pages : 2,\n    api_type : 'PaginatedCollection',\n    item_type : 'City',\n    items : [\n      {\n        id : 35,\n        name : 'San Francisco',\n        lat : 37.777,\n        lng : -124.444,\n        created_at : 1335005399,\n        api_type : 'City'\n      }\n      ...\n    ]\n  }\n}\n```\n\n\n\n#### Utilities\n\n  * version stuff","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaskrabbit%2Fplaybook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftaskrabbit%2Fplaybook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftaskrabbit%2Fplaybook/lists"}