From c16eaac74f8c209a9a67834665762b22177ddec0 Mon Sep 17 00:00:00 2001 From: Alexandru Burlacu Date: Sat, 23 Sep 2017 21:44:09 +0300 Subject: [PATCH 01/14] modify the database schema --- lib/record.ex | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/record.ex b/lib/record.ex index 49cc6c4..e6c415a 100644 --- a/lib/record.ex +++ b/lib/record.ex @@ -2,8 +2,11 @@ defmodule ElixirDocker.Record do use Ecto.Schema schema "records" do - field :count, :integer + field :title, :string + field :description, :string + field :due_date, Ecto.Date + field :priority, :string - timestamps + timestamps() end end From 4ae913e1a7cc4c598bbca8cc39e182b8cbc0824c Mon Sep 17 00:00:00 2001 From: Alexandru Burlacu Date: Sat, 23 Sep 2017 21:50:59 +0300 Subject: [PATCH 02/14] define REST endpoints --- lib/elixir_docker.ex | 21 --------------------- lib/router.ex | 38 ++++++++++++++++++++++++++------------ lib/users.ex | 20 -------------------- 3 files changed, 26 insertions(+), 53 deletions(-) delete mode 100644 lib/elixir_docker.ex delete mode 100644 lib/users.ex diff --git a/lib/elixir_docker.ex b/lib/elixir_docker.ex deleted file mode 100644 index 25f8836..0000000 --- a/lib/elixir_docker.ex +++ /dev/null @@ -1,21 +0,0 @@ -defmodule ElixirDocker do - @moduledoc """ - Documentation for ElixirDocker. - """ - - use Application - alias Users - require Logger - - def start(_type, _args) do - children = [ - Supervisor.Spec.worker(ElixirDocker.Repo, []), - Supervisor.Spec.worker(ElixirDocker.Router, []) - ] - - Logger.info "Started application" - - Supervisor.start_link(children, strategy: :one_for_one, - name: ElixirDocker.Supervisor) - end -end diff --git a/lib/router.ex b/lib/router.ex index 0c5adc2..c65710f 100644 --- a/lib/router.ex +++ b/lib/router.ex @@ -17,25 +17,39 @@ defmodule ElixirDocker.Router do {:ok, _} = Cowboy.http(ElixirDocker.Router, [], port: 8080) end - get "/status" do - if System.get_env("MIX_ENV") == "test" do - timestamp = Ecto.DateTime.from_date_and_time(%Ecto.Date{year: 2017, month: 09, day: 03}, - %Ecto.Time{hour: 12, min: 42, sec: 50, usec: 00}) - last_run = %{inserted_at: timestamp, count: 10} - else - last_run = Record |> Ecto.Query.last |> Repo.one - end - - data = Poison.encode!(%{last_run: last_run.inserted_at, - result_count: last_run.count}) + get "/v1/tasks" do + conn + |> put_resp_content_type("application/json") + |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) + end + + get "/v1/tasks/{id}" do + conn + |> put_resp_content_type("application/json") + |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) + end + + post "/v1/tasks" do + conn + |> put_resp_content_type("application/json") + |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) + end + + put "/v1/tasks/{id}" do + conn + |> put_resp_content_type("application/json") + |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) + end + delete "/v1/tasks/{id}" do conn |> put_resp_content_type("application/json") - |> send_resp(200, data) + |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) end match _ do conn + |> put_resp_content_type("application/json") |> send_resp(404, Poison.encode!(%{endpoint: "not implemented!"})) end end diff --git a/lib/users.ex b/lib/users.ex deleted file mode 100644 index a457817..0000000 --- a/lib/users.ex +++ /dev/null @@ -1,20 +0,0 @@ -defmodule Users do - @moduledoc """ - Documentation for Users module. - """ - - @doc """ - Fetches 10 users from an URL - """ - alias ElixirDocker.Repo - alias ElixirDocker.Record - - def count(url) do - response = HTTPotion.get url - - case Poison.Parser.parse(response.body) do - {:ok, json} -> Repo.insert! %Record{count: length(json)} - _ -> IO.puts "something wrong with the answer" - end - end -end From 1fcdab5532e5092eb79350d00afceb6938e1a1ab Mon Sep 17 00:00:00 2001 From: Alexandru Burlacu Date: Sat, 23 Sep 2017 21:51:19 +0300 Subject: [PATCH 03/14] remove users.ex file --- lib/main.ex | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 lib/main.ex diff --git a/lib/main.ex b/lib/main.ex new file mode 100644 index 0000000..dcaa73d --- /dev/null +++ b/lib/main.ex @@ -0,0 +1,22 @@ +defmodule ElixirDocker do + @moduledoc """ + Documentation for ElixirDocker. + """ + + use Application + alias Users + require Logger + import Supervisor.Spec + + def start(_type, _args) do + children = [ + worker(ElixirDocker.Repo, []), + worker(ElixirDocker.Router, []) + ] + + Logger.info "Started application" + + Supervisor.start_link(children, strategy: :one_for_one, + name: ElixirDocker.Supervisor) + end +end From acaaed26db72be13a9f694b7075cc7610a8deed2 Mon Sep 17 00:00:00 2001 From: Alexandru Burlacu Date: Sat, 23 Sep 2017 22:01:54 +0300 Subject: [PATCH 04/14] add conditional debuger and logger + route wildcards --- lib/router.ex | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/router.ex b/lib/router.ex index c65710f..67cd890 100644 --- a/lib/router.ex +++ b/lib/router.ex @@ -2,10 +2,13 @@ defmodule ElixirDocker.Router do use Plug.Router import Plug.Conn - alias ElixirDocker.Record - alias ElixirDocker.Repo alias Plug.Adapters.Cowboy + if Mix.env == :dev do + use Plug.Debugger + end + + plug Plug.Logger plug :match plug :dispatch @@ -23,7 +26,7 @@ defmodule ElixirDocker.Router do |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) end - get "/v1/tasks/{id}" do + get "/v1/tasks/:id" do conn |> put_resp_content_type("application/json") |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) @@ -35,13 +38,13 @@ defmodule ElixirDocker.Router do |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) end - put "/v1/tasks/{id}" do + put "/v1/tasks/:id" do conn |> put_resp_content_type("application/json") |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) end - delete "/v1/tasks/{id}" do + delete "/v1/tasks/:id" do conn |> put_resp_content_type("application/json") |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) From 26f6904ff65e9ce79623ec14604b6baad6ba6488 Mon Sep 17 00:00:00 2001 From: Alexandru Burlacu Date: Sat, 23 Sep 2017 22:39:42 +0300 Subject: [PATCH 05/14] implement task router as separate module then forward to it --- lib/router.ex | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/lib/router.ex b/lib/router.ex index 67cd890..6f58f18 100644 --- a/lib/router.ex +++ b/lib/router.ex @@ -6,9 +6,9 @@ defmodule ElixirDocker.Router do if Mix.env == :dev do use Plug.Debugger + plug Plug.Logger, log: :debug end - plug Plug.Logger plug :match plug :dispatch @@ -20,39 +20,11 @@ defmodule ElixirDocker.Router do {:ok, _} = Cowboy.http(ElixirDocker.Router, [], port: 8080) end - get "/v1/tasks" do - conn - |> put_resp_content_type("application/json") - |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) - end - - get "/v1/tasks/:id" do - conn - |> put_resp_content_type("application/json") - |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) - end - - post "/v1/tasks" do - conn - |> put_resp_content_type("application/json") - |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) - end - - put "/v1/tasks/:id" do - conn - |> put_resp_content_type("application/json") - |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) - end - - delete "/v1/tasks/:id" do - conn - |> put_resp_content_type("application/json") - |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) - end + forward "/v1/tasks", to: TasksRouter match _ do conn |> put_resp_content_type("application/json") |> send_resp(404, Poison.encode!(%{endpoint: "not implemented!"})) end -end +end \ No newline at end of file From e9a7f8b60cbc9ed6823c97697058ab595a55af0d Mon Sep 17 00:00:00 2001 From: Alexandru Burlacu Date: Sat, 23 Sep 2017 22:39:55 +0300 Subject: [PATCH 06/14] implement task router as separate module then forward to it --- lib/task_router.ex | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 lib/task_router.ex diff --git a/lib/task_router.ex b/lib/task_router.ex new file mode 100644 index 0000000..bcdfb47 --- /dev/null +++ b/lib/task_router.ex @@ -0,0 +1,32 @@ +defmodule TasksRouter do + use Plug.Router + + plug :match + plug :dispatch + + defp common_behaviour(connection) do + connection + |> put_resp_content_type("application/json") + |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) + end + + post "/" do + common_behaviour(conn) + end + + get "/" do + common_behaviour(conn) + end + + get "/:id" do + common_behaviour(conn) + end + + put "/:id" do + common_behaviour(conn) + end + + delete "/:id" do + common_behaviour(conn) + end +end \ No newline at end of file From c01a2bc47bb71ac8a3a388957f39a3d69a429191 Mon Sep 17 00:00:00 2001 From: Alexandru Burlacu Date: Sat, 23 Sep 2017 22:43:22 +0300 Subject: [PATCH 07/14] small fixes --- lib/main.ex | 1 - lib/record.ex | 2 +- lib/router.ex | 1 + lib/task_router.ex | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/main.ex b/lib/main.ex index dcaa73d..5fe66d9 100644 --- a/lib/main.ex +++ b/lib/main.ex @@ -4,7 +4,6 @@ defmodule ElixirDocker do """ use Application - alias Users require Logger import Supervisor.Spec diff --git a/lib/record.ex b/lib/record.ex index e6c415a..631b9c8 100644 --- a/lib/record.ex +++ b/lib/record.ex @@ -1,7 +1,7 @@ defmodule ElixirDocker.Record do use Ecto.Schema - schema "records" do + schema "tasks" do field :title, :string field :description, :string field :due_date, Ecto.Date diff --git a/lib/router.ex b/lib/router.ex index 6f58f18..52d0de7 100644 --- a/lib/router.ex +++ b/lib/router.ex @@ -3,6 +3,7 @@ defmodule ElixirDocker.Router do import Plug.Conn alias Plug.Adapters.Cowboy + alias ElixirDocker.Router.TasksRouter if Mix.env == :dev do use Plug.Debugger diff --git a/lib/task_router.ex b/lib/task_router.ex index bcdfb47..8ff68cc 100644 --- a/lib/task_router.ex +++ b/lib/task_router.ex @@ -1,4 +1,4 @@ -defmodule TasksRouter do +defmodule ElixirDocker.Router.TasksRouter do use Plug.Router plug :match From a0df63d8ce34403316736df73600d46e31ccf49f Mon Sep 17 00:00:00 2001 From: Alexandru Burlacu Date: Sat, 23 Sep 2017 22:55:26 +0300 Subject: [PATCH 08/14] migration: create table tasks --- lib/record.ex | 2 +- lib/task_router.ex | 3 +++ mix.exs | 4 ++-- .../migrations/20170923195206_change_schema.exs | 16 ++++++++++++++++ 4 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 priv/repo/migrations/20170923195206_change_schema.exs diff --git a/lib/record.ex b/lib/record.ex index 631b9c8..23022b8 100644 --- a/lib/record.ex +++ b/lib/record.ex @@ -4,7 +4,7 @@ defmodule ElixirDocker.Record do schema "tasks" do field :title, :string field :description, :string - field :due_date, Ecto.Date + field :due_date, :date field :priority, :string timestamps() diff --git a/lib/task_router.ex b/lib/task_router.ex index 8ff68cc..c358070 100644 --- a/lib/task_router.ex +++ b/lib/task_router.ex @@ -2,6 +2,9 @@ defmodule ElixirDocker.Router.TasksRouter do use Plug.Router plug :match + plug Plug.Parsers, parsers: [:json], + pass: ["application/json"], + json_decoder: Poison plug :dispatch defp common_behaviour(connection) do diff --git a/mix.exs b/mix.exs index 0d0965c..b2c6c99 100644 --- a/mix.exs +++ b/mix.exs @@ -26,9 +26,9 @@ defmodule ElixirDocker.Mixfile do {:cowboy, "~> 1.1.2"}, {:plug, "~> 1.3.4"}, {:postgrex, ">= 0.0.0"}, - {:ecto, "~> 2.0.0-beta"}, + {:ecto, "~> 2.1.0"}, {:httpotion, "~> 2.1.0"}, - {:poison, "~> 1.5"}, + {:poison, "~> 2.2"}, {:ibrowse, github: "cmullaparthi/ibrowse", tag: "v4.1.2"}, # for dev and test purpose only {:excoveralls, github: "parroty/excoveralls", only: :test}, diff --git a/priv/repo/migrations/20170923195206_change_schema.exs b/priv/repo/migrations/20170923195206_change_schema.exs new file mode 100644 index 0000000..8dcbbd4 --- /dev/null +++ b/priv/repo/migrations/20170923195206_change_schema.exs @@ -0,0 +1,16 @@ +defmodule ElixirDocker.Repo.Migrations.ChangeSchema do + use Ecto.Migration + + def change do + drop table(:records) + + create table(:tasks) do + add :title, :string + add :description, :string + add :due_date, :date + add :priority, :string + + timestamps + end + end +end From cb2e52161654f24ecd0f31a7e6c46cc13d07ca7a Mon Sep 17 00:00:00 2001 From: Alexandru Burlacu Date: Sun, 24 Sep 2017 12:50:15 +0300 Subject: [PATCH 09/14] implement dumb logic for all endpoints + add brief documentation to modules --- lib/main.ex | 6 +++--- lib/record.ex | 4 ++++ lib/repo.ex | 4 ++++ lib/router.ex | 6 +++++- lib/task_router.ex | 32 ++++++++++++++++++++++++-------- 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/lib/main.ex b/lib/main.ex index 5fe66d9..65927d5 100644 --- a/lib/main.ex +++ b/lib/main.ex @@ -1,11 +1,11 @@ defmodule ElixirDocker do @moduledoc """ - Documentation for ElixirDocker. + Entry point and handler for ElixirDocker app. """ - + use Application require Logger - import Supervisor.Spec + import Supervisor.Spec def start(_type, _args) do children = [ diff --git a/lib/record.ex b/lib/record.ex index 23022b8..29e4224 100644 --- a/lib/record.ex +++ b/lib/record.ex @@ -1,4 +1,8 @@ defmodule ElixirDocker.Record do + @moduledoc """ + Describes the 'tasks' table in the Database. + """ + use Ecto.Schema schema "tasks" do diff --git a/lib/repo.ex b/lib/repo.ex index 4f470ce..1d2d5d5 100644 --- a/lib/repo.ex +++ b/lib/repo.ex @@ -1,3 +1,7 @@ defmodule ElixirDocker.Repo do + @moduledoc """ + I think it binds the Ecto Repository to the app. + """ + use Ecto.Repo, otp_app: :elixir_docker end diff --git a/lib/router.ex b/lib/router.ex index 52d0de7..b00c962 100644 --- a/lib/router.ex +++ b/lib/router.ex @@ -1,4 +1,8 @@ defmodule ElixirDocker.Router do + @moduledoc """ + Top level router of the TODO API. + """ + use Plug.Router import Plug.Conn @@ -28,4 +32,4 @@ defmodule ElixirDocker.Router do |> put_resp_content_type("application/json") |> send_resp(404, Poison.encode!(%{endpoint: "not implemented!"})) end -end \ No newline at end of file +end diff --git a/lib/task_router.ex b/lib/task_router.ex index c358070..3b7d239 100644 --- a/lib/task_router.ex +++ b/lib/task_router.ex @@ -1,5 +1,11 @@ defmodule ElixirDocker.Router.TasksRouter do + @moduledoc """ + Special purpose router to handle + CRUD operations over 'tasks' in the TODO API. + """ + use Plug.Router + require Logger plug :match plug Plug.Parsers, parsers: [:json], @@ -7,29 +13,39 @@ defmodule ElixirDocker.Router.TasksRouter do json_decoder: Poison plug :dispatch - defp common_behaviour(connection) do + defp common_behaviour(connection, data) do connection |> put_resp_content_type("application/json") - |> send_resp(200, Poison.encode!(%{data: "Nothing to show"})) + |> send_resp(200, Poison.encode!(data)) end post "/" do - common_behaviour(conn) + conn + |> common_behaviour(%{info: "Welcome from post", + data: conn.body_params}) end get "/" do - common_behaviour(conn) + conn + |> common_behaviour(%{info: "Welcome from listing", + data: [%{no: "posts"}, %{no: "posts"}]}) end get "/:id" do - common_behaviour(conn) + conn + |> common_behaviour(%{info: "Welcome from details", + data: %{no: "info on #{id}"}}) end put "/:id" do - common_behaviour(conn) + conn + |> common_behaviour(%{info: "Welcome from update", + data: %{no: "way to update #{id}"}}) end delete "/:id" do - common_behaviour(conn) + conn + |> common_behaviour(%{info: "Welcome from delete", + data: %{no: "way to delete #{id}"}}) end -end \ No newline at end of file +end From d02c6ecb670c9391e708038f4ca828a88ab2a97e Mon Sep 17 00:00:00 2001 From: Alexandru Burlacu Date: Sun, 24 Sep 2017 15:09:53 +0300 Subject: [PATCH 10/14] implement POST endpoint --- lib/task_router.ex | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/lib/task_router.ex b/lib/task_router.ex index 3b7d239..48d5d0c 100644 --- a/lib/task_router.ex +++ b/lib/task_router.ex @@ -5,7 +5,9 @@ defmodule ElixirDocker.Router.TasksRouter do """ use Plug.Router - require Logger + + alias ElixirDocker.Record + alias ElixirDocker.Repo plug :match plug Plug.Parsers, parsers: [:json], @@ -13,39 +15,60 @@ defmodule ElixirDocker.Router.TasksRouter do json_decoder: Poison plug :dispatch - defp common_behaviour(connection, data) do + defp response(connection, code, data) do connection |> put_resp_content_type("application/json") - |> send_resp(200, Poison.encode!(data)) + |> send_resp(code, Poison.encode!(data)) + end + + defp valid_data?(data) do + ["title", "description", "due_date", "priority"] + |> Enum.map(fn k -> + data + |> Map.has_key?(k) + end) + |> Enum.all? end post "/" do - conn - |> common_behaviour(%{info: "Welcome from post", - data: conn.body_params}) + data = conn.body_params + + if (valid_data?(data)) do + + record = %Record{title: data["title"], + description: data["description"], + due_date: Date.from_iso8601!(data["due_date"]), + priority: data["priority"]} + + resp = Repo.insert! record + + conn |> response(201, %{info: "Task created", task_id: resp.id}) + else + conn |> response(400, %{info: "Invalid body"}) + end end get "/" do conn - |> common_behaviour(%{info: "Welcome from listing", + |> response(200, %{info: "Welcome from listing", data: [%{no: "posts"}, %{no: "posts"}]}) end get "/:id" do conn - |> common_behaviour(%{info: "Welcome from details", + |> response(200, %{info: "Welcome from details", data: %{no: "info on #{id}"}}) end put "/:id" do conn - |> common_behaviour(%{info: "Welcome from update", + |> response(200, %{info: "Welcome from update", data: %{no: "way to update #{id}"}}) end delete "/:id" do conn - |> common_behaviour(%{info: "Welcome from delete", + |> response(200, %{info: "Welcome from delete", data: %{no: "way to delete #{id}"}}) end end From 8f6cee6f45bf28d0224b76ab7d0ef86f8fea704f Mon Sep 17 00:00:00 2001 From: Alexandru Burlacu Date: Sun, 24 Sep 2017 16:25:45 +0300 Subject: [PATCH 11/14] implement logic fot GET endpoints --- lib/task_router.ex | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/lib/task_router.ex b/lib/task_router.ex index 48d5d0c..f138a81 100644 --- a/lib/task_router.ex +++ b/lib/task_router.ex @@ -5,6 +5,7 @@ defmodule ElixirDocker.Router.TasksRouter do """ use Plug.Router + import Ecto.Query alias ElixirDocker.Record alias ElixirDocker.Repo @@ -30,6 +31,17 @@ defmodule ElixirDocker.Router.TasksRouter do |> Enum.all? end + defp stringify_dates(raw_data) do + raw_data |> Enum.map(fn record -> + {{y, m, d}, _} = record.inserted_at + {due_y, due_m, due_d} = record.due_date + + record + |> Map.put(:inserted_at, "#{y}-#{m}-#{d}") + |> Map.put(:due_date, "#{due_y}-#{due_m}-#{due_d}") + end) + end + post "/" do data = conn.body_params @@ -49,15 +61,24 @@ defmodule ElixirDocker.Router.TasksRouter do end get "/" do - conn - |> response(200, %{info: "Welcome from listing", - data: [%{no: "posts"}, %{no: "posts"}]}) + data = Repo.all(from t in "tasks", + select: [:title, :description, + :due_date, :priority, + :inserted_at, :id]) + + conn |> response(200, %{info: "The available tasks", + data: stringify_dates(data)}) end get "/:id" do - conn - |> response(200, %{info: "Welcome from details", - data: %{no: "info on #{id}"}}) + data = Repo.all(from t in "tasks", + where: t.id == ^String.to_integer(id), + select: [:title, :description, + :due_date, :priority, + :inserted_at]) + + conn |> response(200, %{info: "Information about tasks ##{id}", + data: stringify_dates(data)}) end put "/:id" do From 11b00989dfaa42538e7872718c895c4d0c4b50c8 Mon Sep 17 00:00:00 2001 From: Alexandru Burlacu Date: Mon, 25 Sep 2017 11:30:10 +0300 Subject: [PATCH 12/14] add corect return codes for existing REST methods + implement DELETE --- lib/task_router.ex | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/task_router.ex b/lib/task_router.ex index f138a81..cdbd9c6 100644 --- a/lib/task_router.ex +++ b/lib/task_router.ex @@ -60,6 +60,10 @@ defmodule ElixirDocker.Router.TasksRouter do end end + post "/:id" do + conn |> response(405, %{info: "Impossible to update tasks via POST, use PUT instead"}) + end + get "/" do data = Repo.all(from t in "tasks", select: [:title, :description, @@ -77,19 +81,34 @@ defmodule ElixirDocker.Router.TasksRouter do :due_date, :priority, :inserted_at]) - conn |> response(200, %{info: "Information about tasks ##{id}", - data: stringify_dates(data)}) + case (data) do + [] -> conn |> response(404, %{info: "No information about tasks ##{id}"}) + _ -> conn |> response(200, %{info: "Information about tasks ##{id}", + data: stringify_dates(data)}) + end + end + + put "/" do + conn |> response(405, %{info: "Impossible to update all tasks"}) end put "/:id" do conn |> response(200, %{info: "Welcome from update", - data: %{no: "way to update #{id}"}}) + data: %{no: "way to update #{id}"}}) + end + + delete "/" do + conn |> response(405, %{info: "Impossible to delete all tasks"}) end delete "/:id" do - conn - |> response(200, %{info: "Welcome from delete", - data: %{no: "way to delete #{id}"}}) + stats = Ecto.Adapters.SQL.query(Repo, + "DELETE FROM tasks WHERE id = $1", [String.to_integer id]) + + case (stats) do + {:ok, _} -> conn |> response(200, %{info: "Task ##{id} deleted"}) + {:error, _} -> conn |> response(700, %{info: "Task ##{id} not deleted"}) + end end end From 46a1e202b701c61bdb9b5af779cd1e08e31905cb Mon Sep 17 00:00:00 2001 From: Alexandru Burlacu Date: Mon, 25 Sep 2017 11:31:38 +0300 Subject: [PATCH 13/14] add corect return codes for existing REST methods + implement DELETE --- lib/task_router.ex | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/task_router.ex b/lib/task_router.ex index cdbd9c6..3eed7ec 100644 --- a/lib/task_router.ex +++ b/lib/task_router.ex @@ -93,6 +93,7 @@ defmodule ElixirDocker.Router.TasksRouter do end put "/:id" do + IO.puts inspect conn.body_params conn |> response(200, %{info: "Welcome from update", data: %{no: "way to update #{id}"}}) From b57f3e164567a1c3245b1a344ad47cd719a21d1c Mon Sep 17 00:00:00 2001 From: Alexandru Burlacu Date: Mon, 25 Sep 2017 12:07:29 +0300 Subject: [PATCH 14/14] implement PUT endpoint - it's quite awful tho --- lib/task_router.ex | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/lib/task_router.ex b/lib/task_router.ex index 3eed7ec..0ebcf75 100644 --- a/lib/task_router.ex +++ b/lib/task_router.ex @@ -45,18 +45,16 @@ defmodule ElixirDocker.Router.TasksRouter do post "/" do data = conn.body_params - if (valid_data?(data)) do + case (valid_data?(data)) do + true -> record = %Record{title: data["title"], + description: data["description"], + due_date: Date.from_iso8601!(data["due_date"]), + priority: data["priority"]} - record = %Record{title: data["title"], - description: data["description"], - due_date: Date.from_iso8601!(data["due_date"]), - priority: data["priority"]} + resp = Repo.insert! record - resp = Repo.insert! record - - conn |> response(201, %{info: "Task created", task_id: resp.id}) - else - conn |> response(400, %{info: "Invalid body"}) + conn |> response(201, %{info: "Task created", task_id: resp.id}) + false -> conn |> response(400, %{info: "Invalid body"}) end end @@ -69,9 +67,11 @@ defmodule ElixirDocker.Router.TasksRouter do select: [:title, :description, :due_date, :priority, :inserted_at, :id]) - - conn |> response(200, %{info: "The available tasks", - data: stringify_dates(data)}) + case (data) do + [] -> conn |> response(404, %{info: "No available tasks"}) + _ -> conn |> response(200, %{info: "The available tasks", + data: stringify_dates(data)}) + end end get "/:id" do @@ -93,10 +93,19 @@ defmodule ElixirDocker.Router.TasksRouter do end put "/:id" do - IO.puts inspect conn.body_params - conn - |> response(200, %{info: "Welcome from update", - data: %{no: "way to update #{id}"}}) + data = conn.body_params + + case (valid_data?(data)) do + true -> resp = from(t in "tasks", where: t.id == ^String.to_integer(id), + update: [set: [title: ^data["title"], + description: ^data["description"], + due_date: ^Date.from_iso8601!(data["due_date"]), + priority: ^data["priority"]]]) + |> Repo.update_all([]) + + conn |> response(200, %{info: "Task ##{id} updated"}) + false -> conn |> response(400, %{info: "Invalid body"}) + end end delete "/" do