adds rest api connector

- routing setup with path to message_controller
- messages api to database updated to function
  similar to a stack system (push, pop, peek, ..)
- rest calls the same as database calls
- setup default controller showing text message
- parsing database output with Jason to client
- adds curl examples
This commit is contained in:
Raphael Maenle 2021-12-10 15:34:38 +01:00
parent 3b1657e18a
commit 5d50bb30e6
6 changed files with 91 additions and 47 deletions

View File

@ -26,6 +26,6 @@ Ready to run in production? Please [check our deployment guides](https://hexdocs
## TODOs ## TODOs
[x] finish api calls in lib/bump/messages.ex [x] finish api calls in lib/bump/messages.ex
[] [x] add rest api and connect to database api

5
curl.sh Normal file
View File

@ -0,0 +1,5 @@
curl -X POST http://localhost:4000/api/push -H "Content-Type: application/json" -d '{"sender": "raphael", "message": "Hello"}'
# curl -X POST http://localhost:4000/api/peak -H "Content-Type: application/json" -d '{"sender": "raphael"}'
# curl -X POST http://localhost:4000/api/pop -H "Content-Type: application/json" -d '{"sender": "raphael"}'
# curl -X POST http://localhost:4000/api/list -H "Content-Type: application/json" -d '{"sender": "raphael", "minutes": "40"}'
# curl -X POST http://localhost:4000/api/clear -H "Content-Type: application/json" -d '{"sender": "raphael"}'

View File

@ -3,39 +3,56 @@ defmodule Bump.Messages do
alias Bump.Messages.Message alias Bump.Messages.Message
import Ecto.Query import Ecto.Query
def get_newest_message(sender) do def pop(sender) do
query = from m in "messages", query = from m in "messages",
where: m.sender == ^sender, where: m.sender == ^sender,
order_by: [desc: m.timestamp], order_by: [desc: m.timestamp],
limit: 1, limit: 1,
select: m.data select: %{id: m.id, data: m.data, timestamp: m.timestamp}
res = Repo.one(query)
if not is_nil(res) do
Repo.delete_all(from m in "messages", where: m.id == ^res.id)
%{data: res.data, timestamp: res.timestamp}
else
nil
end
end
def peak(sender) do
query = from m in "messages",
where: m.sender == ^sender,
order_by: [desc: m.timestamp],
limit: 1,
select: %{data: m.data, timestamp: m.timestamp}
Repo.one(query) Repo.one(query)
end end
def get_all_messages_since(sender, minutes) do def list(sender, minutes) do
ago = DateTime.utc_now ago = DateTime.utc_now
|> Timex.shift(minutes: -minutes) |> Timex.shift(minutes: -minutes)
|> DateTime.truncate(:second) |> DateTime.truncate(:second)
query = from m in "messages", query = from m in "messages",
where: m.sender == ^sender and where: m.sender == ^sender and
m.timestamp >= ^ago, m.timestamp >= ^ago,
select: m.data select: %{data: m.data, timestamp: m.timestamp}
Repo.all(query) Repo.all(query)
end end
def remove_sender(sender) do def clear(sender) do
query = from m in "messages", query = from m in "messages",
where: m.sender == ^sender, where: m.sender == ^sender
select: m.id
Repo.delete_all(query) Repo.delete_all(query)
end end
def add_message(sender, message) do def push(sender, message) do
time = time = DateTime.utc_now |> DateTime.truncate(:second)
DateTime.utc_now
|> DateTime.truncate(:second)
Repo.insert(%Message{sender: sender, data: message, timestamp: time}) Repo.insert(%Message{sender: sender, data: message, timestamp: time})

View File

@ -1,7 +1,7 @@
defmodule BumpWeb.PageController do defmodule BumpWeb.DefaultController do
use BumpWeb, :controller use BumpWeb, :controller
def index(conn, _params) do def index(conn, _params) do
render(conn, "index.html") text conn, "Bump API"
end end
end end

View File

@ -0,0 +1,37 @@
defmodule BumpWeb.MessageController do
use BumpWeb, :controller
alias Bump.Messages
def index(conn, _params) do
text conn, "Bump Api"
end
def list(conn, %{"sender" => sender, "minutes" => minutes}) do
list = Messages.list(sender, String.to_integer(minutes))
text conn, Jason.encode!(list)
end
def clear(conn, %{"sender" => sender}) do
Messages.clear(sender)
text conn, "OK"
end
def push(conn, %{"sender" => sender, "message" => message}) do
Messages.push(sender, message)
text conn, "OK"
end
def pop(conn, %{"sender" => sender}) do
message = Messages.pop(sender)
text conn, Jason.encode!(message)
end
def peak(conn, %{"sender" => sender}) do
message = Messages.peak(sender)
text conn, Jason.encode!(message)
end
end

View File

@ -1,25 +1,28 @@
defmodule BumpWeb.Router do defmodule BumpWeb.Router do
use BumpWeb, :router use BumpWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, {BumpWeb.LayoutView, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do pipeline :api do
plug :accepts, ["json"] plug :accepts, ["json"]
end end
scope "/", BumpWeb do scope "/api", BumpWeb do
pipe_through :browser pipe_through :api
post "/push", MessageController, :push
get "/", PageController, :index post "/peak", MessageController, :peak
post "/pop", MessageController, :pop
post "/list", MessageController, :list
post "/clear", MessageController, :clear
end end
pipeline :browser do
plug :accepts, ["html"]
end
scope "/", BumpWeb do
pipe_through :browser
get "/", DefaultController, :index
end
# Other scopes may use custom stacks. # Other scopes may use custom stacks.
# scope "/api", BumpWeb do # scope "/api", BumpWeb do
# pipe_through :api # pipe_through :api
@ -33,23 +36,5 @@ defmodule BumpWeb.Router do
# you can use Plug.BasicAuth to set up some basic authentication # you can use Plug.BasicAuth to set up some basic authentication
# as long as you are also using SSL (which you should anyway). # as long as you are also using SSL (which you should anyway).
if Mix.env() in [:dev, :test] do if Mix.env() in [:dev, :test] do
import Phoenix.LiveDashboard.Router
scope "/" do
pipe_through :browser
live_dashboard "/dashboard", metrics: BumpWeb.Telemetry
end
end
# Enables the Swoosh mailbox preview in development.
#
# Note that preview only shows emails that were sent by the same
# node running the Phoenix server.
if Mix.env() == :dev do
scope "/dev" do
pipe_through :browser
forward "/mailbox", Plug.Swoosh.MailboxPreview
end
end end
end end