Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ My experience and knowledge about Elixir is very basic. So be prepared to find m

## Tutorial

### [Part 1 - Basic Setup](./tutorial/part1.md)
#### [Part 1 - Basic Setup](./tutorial/part1.md)
#### [Part 2 - The first REST resource (Work in progress)](./tutorial/part2.md)
7 changes: 7 additions & 0 deletions server/lib/data/article.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
defmodule Data.Article do
defstruct [:id ,:href ,:title]

def from_json_map map do
%Data.Article{id: map["id"], href: map["href"], title: map["title"]}
end
end
3 changes: 2 additions & 1 deletion server/lib/server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ defmodule Server do
children = [
# Define workers and child supervisors to be supervised
# worker(Server.Worker, [arg1, arg2, arg3]),
Plug.Adapters.Cowboy.child_spec(:http, Server.Routes, [], port: 8080)
Plug.Adapters.Cowboy.child_spec(:http, Server.Routes, [], port: 8080),
worker(Storage.Articles, [])
]

# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
Expand Down
2 changes: 2 additions & 0 deletions server/lib/server/routes.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ defmodule Server.Routes do
|> send_resp(200, Poison.encode!(data))
end

forward "/articles", to: Server.Routes.Articles

match _ do
send_resp(conn, 404, "you shall not pass")
end
Expand Down
37 changes: 37 additions & 0 deletions server/lib/server/routes/articles.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
defmodule Server.Routes.Articles do
use Plug.Router

plug Plug.Logger, log: :debug
plug Plug.Parsers, parsers: [:json], json_decoder: Poison
plug :match
plug :dispatch

get "/" do
data = Storage.Articles.list()
conn
|> set_json_resp
|> send_resp(200, Poison.encode!(data))
end

get "/:aid" do
data = Storage.Articles.find(aid)

case data do
nil -> conn |> set_json_resp |> send_resp(404, Poison.encode!(%{message: "not found"}))
data -> conn |> set_json_resp |> send_resp(200, Poison.encode!(data))
end
end

post "/" do
new_article = Data.Article.from_json_map(conn.params)

new_article = Storage.Articles.create(new_article)

conn
|> put_resp_header("Location","/articles/" <> new_article.id)
|> send_resp(201,"")
end

defp set_json_resp(conn), do: conn |> put_resp_header("Content-Type","application/json")

end
67 changes: 67 additions & 0 deletions server/lib/storage/articles.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
defmodule Storage.Articles do
use GenServer

# Interface

def start_link do
articles = [
%Data.Article{id: "1", href: "http://example.com/article1", title: "Funny Article"},
%Data.Article{id: "2", href: "http://example.com/article2", title: "Important Article"}
]
GenServer.start_link(__MODULE__, articles, [name: __MODULE__])
end

def list do
GenServer.call(__MODULE__,{:list})
end

def find id do
GenServer.call(__MODULE__, {:find, id})
end

def create %Data.Article{} = article do
GenServer.call(__MODULE__, {:create, article})
end

# Server

def init articles do
{:ok, articles}
end

def handle_call({:list}, _from, articles) do
{:reply, articles, articles}
end

def handle_call({:find, id}, _from, articles) do
article = find(articles, id)
{:reply, article, articles}
end

def handle_call({:create, article}, _from, articles) do
article = %Data.Article{article| id: create_new_id(articles)}
{:reply, article, [article| articles]}
end


defp find(articles, id) do
articles |> Enum.find(fn(article) -> article.id == id end)
end

defp create_new_id(articles) do
id = create_random_id()

case find(articles, id) do
nil -> id
_ -> create_new_id(articles)
end
end

defp create_random_id do
alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
alphabet_length = String.length(alphabet)
0..31 |> Enum.map_join(fn(_) ->
String.at(alphabet, :random.uniform(alphabet_length) - 1)
end)
end
end
4 changes: 2 additions & 2 deletions server/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ defmodule Server.Mixfile do
# Type "mix help deps" for more examples and options
defp deps do
[{:cowboy, "~> 1.0.4"},
{:plug, "~> 1.1.0"},
{:poison, "~> 1.4.0"}]
{:plug, "~> 1.1.1"},
{:poison, "~> 2.1.0"}]
end
end
2 changes: 1 addition & 1 deletion server/mix.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%{"cowboy": {:hex, :cowboy, "1.0.4"},
"cowlib": {:hex, :cowlib, "1.0.2"},
"plug": {:hex, :plug, "1.1.1"},
"poison": {:hex, :poison, "1.4.0"},
"poison": {:hex, :poison, "2.1.0"},
"ranch": {:hex, :ranch, "1.2.1"}}
Loading