diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 6f54c8a..443f100 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -3,11 +3,10 @@
-
-
-
-
-
+
+
+
+
@@ -46,11 +45,61 @@
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -59,7 +108,7 @@
-
+
@@ -132,7 +181,6 @@
-
@@ -142,6 +190,12 @@
+
+
+
+
+
+
@@ -189,6 +243,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -208,6 +282,11 @@
+
+
+
+
+
-
+
@@ -382,34 +461,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -466,13 +517,6 @@
-
-
-
-
-
-
-
@@ -487,13 +531,6 @@
-
-
-
-
-
-
-
@@ -608,13 +645,6 @@
-
-
-
-
-
-
-
@@ -722,18 +752,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/app/controllers/items_controller.rb b/app/controllers/items_controller.rb
deleted file mode 100644
index d8e3286..0000000
--- a/app/controllers/items_controller.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-class ItemsController < ApplicationController
- before_action :set_todo
- before_action :set_todo_item, only: [:show, :update, :destroy]
-
- # GET /todos/:todo_id/items
- def index
- json_response(@todo.items)
- end
-
- # GET /todos/:todo_id/items/:id
- def show
- json_response(@item)
- end
-
- # POST /todos/:todo_id/items
- def create
- @todo.items.create!(item_params)
- json_response(@todo, :created)
- end
-
- # PUT /todos/:todo_id/items/:d
- def update
- @item.update(item_params)
- head :no_content
- end
-
- # DELETE /todos/:todo_id/items/:id
- def destroy
- @item.destroy
- head :no_content
- end
-
- private
-
- def item_params
- params.permit(:name, :done)
- end
-
- def set_todo
- @todo = Todo.find(params[:todo_id])
- end
-
- def set_todo_item
- @item = @todo.items.find_by!(id: params[:id]) if @todo
- end
-
-end
diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb
deleted file mode 100644
index 204d4bb..0000000
--- a/app/controllers/todos_controller.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-class TodosController < ApplicationController
- before_action :set_todo, only: [:show, :update, :destroy]
-
- # GET /todos
- def index
- @todos = current_user.todos
- json_response(@todos)
- end
-
- # POST /todos
- def create
- @todo = current_user.todos.create!(todo_params)
- json_response(@todo, :created)
- end
-
- # GET /todos/:id
- def show
- json_response(@todo)
- end
-
- # PUT /todos/:id
- def update
- @todo.update(todo_params)
- head :no_content
- end
-
- # DELETE /todos/:id
- def destroy
- @todo.destroy
- head :no_content
- end
-
- private
-
- def todo_params
- # whitelist params
- params.permit(:title)
- end
-
- def set_todo
- @todo = Todo.find(params[:id])
- end
-
-end
diff --git a/app/controllers/articles_controller.rb b/app/controllers/v1/articles_controller.rb
similarity index 94%
rename from app/controllers/articles_controller.rb
rename to app/controllers/v1/articles_controller.rb
index 1c0207a..4732689 100644
--- a/app/controllers/articles_controller.rb
+++ b/app/controllers/v1/articles_controller.rb
@@ -1,4 +1,4 @@
-class ArticlesController < ApplicationController
+class V1::ArticlesController < ApplicationController
before_action :set_article, only: [:show, :update, :destroy]
skip_before_action :authorize_request, only: [:index, :show]
diff --git a/app/controllers/v1/items_controller.rb b/app/controllers/v1/items_controller.rb
new file mode 100644
index 0000000..4f65f06
--- /dev/null
+++ b/app/controllers/v1/items_controller.rb
@@ -0,0 +1,48 @@
+module V1
+ class ItemsController < ApplicationController
+ before_action :set_todo
+ before_action :set_todo_item, only: [:show, :update, :destroy]
+
+ # GET /todos/:todo_id/items
+ def index
+ json_response(@todo.items)
+ end
+
+ # GET /todos/:todo_id/items/:id
+ def show
+ json_response(@item)
+ end
+
+ # POST /todos/:todo_id/items
+ def create
+ @todo.items.create!(item_params)
+ json_response(@todo, :created)
+ end
+
+ # PUT /todos/:todo_id/items/:d
+ def update
+ @item.update(item_params)
+ head :no_content
+ end
+
+ # DELETE /todos/:todo_id/items/:id
+ def destroy
+ @item.destroy
+ head :no_content
+ end
+
+ private
+
+ def item_params
+ params.permit(:name, :done)
+ end
+
+ def set_todo
+ @todo = Todo.find(params[:todo_id])
+ end
+
+ def set_todo_item
+ @item = @todo.items.find_by!(id: params[:id]) if @todo
+ end
+ end
+end
diff --git a/app/controllers/v1/todos_controller.rb b/app/controllers/v1/todos_controller.rb
new file mode 100644
index 0000000..81f6f0e
--- /dev/null
+++ b/app/controllers/v1/todos_controller.rb
@@ -0,0 +1,45 @@
+module V1
+ class TodosController < ApplicationController
+ before_action :set_todo, only: [:show, :update, :destroy]
+
+ # GET /todos
+ def index
+ @todos = current_user.todos
+ json_response(@todos)
+ end
+
+ # POST /todos
+ def create
+ @todo = current_user.todos.create!(todo_params)
+ json_response(@todo, :created)
+ end
+
+ # GET /todos/:id
+ def show
+ json_response(@todo)
+ end
+
+ # PUT /todos/:id
+ def update
+ @todo.update(todo_params)
+ head :no_content
+ end
+
+ # DELETE /todos/:id
+ def destroy
+ @todo.destroy
+ head :no_content
+ end
+
+ private
+
+ def todo_params
+ # whitelist params
+ params.permit(:title)
+ end
+
+ def set_todo
+ @todo = Todo.find(params[:id])
+ end
+ end
+end
diff --git a/app/controllers/v2/articles_controller.rb b/app/controllers/v2/articles_controller.rb
new file mode 100644
index 0000000..a2c00f1
--- /dev/null
+++ b/app/controllers/v2/articles_controller.rb
@@ -0,0 +1,5 @@
+class V2::ArticlesController < ApplicationController
+ def index
+ json_response({message: 'Version 2 not implemented'})
+ end
+end
diff --git a/app/lib/api_version.rb b/app/lib/api_version.rb
new file mode 100644
index 0000000..3d65e3f
--- /dev/null
+++ b/app/lib/api_version.rb
@@ -0,0 +1,21 @@
+class ApiVersion
+ attr_reader :version, :default
+
+ def initialize(version, default = false)
+ @version = version
+ @default = default
+ end
+
+ # check whether version is specified or is default
+ def matches?(request)
+ check_headers(request.headers) || default
+ end
+
+ private
+
+ def check_headers(headers)
+ # check version from Accept headers; expect custom media type `todos`
+ accept = headers[:accept]
+ accept && accept.include?("application/vnd.rails.#{version}+json") # header Accept: application/vnd.rails.v#+json
+ end
+end
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 67de6eb..d142c5e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,9 +1,17 @@
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
- resources :todos do
- resources :items
+
+ scope module: :v2, constraints: ApiVersion.new('v2') do
+ resources :articles
end
- resources :articles
+
+ scope module: :v1, constraints: ApiVersion.new('v1', true) do
+ resources :todos do
+ resources :items
+ end
+ resources :articles
+ end
+
resources :users
post 'auth/login', to: 'authentication#authenticate'
post 'signup', to: 'users#create'
diff --git a/spec/controllers/v2/articles_controller_spec.rb b/spec/controllers/v2/articles_controller_spec.rb
new file mode 100644
index 0000000..2e3b628
--- /dev/null
+++ b/spec/controllers/v2/articles_controller_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe V2::ArticlesController, type: :controller do
+
+end