Ever wondered how to write a small REST APi for your frontend or for public usage? - here is how.
Requirements:
- Elixir v13.3.2 +
- Phoenix v1.6.10+
- Basic Knowledge of Elixir
$ elixir -v
Elixir 1.13.2 (compiled with Erlang/OTP 24)
$ mix phx.new --version
Phoenix installer v1.6.10
Getting started
Lets start with creating our Project with the following command
$ mix phx.new myApp --no-html --no-assets --no-mailer --no-dashboard --no-ecto
This will remove all the useless boilerplate for us - since APis do not need any HTML or CSS.
Now lets path into your folder:
$ cd myApp
Lets open our router first lib/myapp_web/router.ex
, there, add the following code
get "/random", RandomController, :index
Your Router should now look like this:
defmodule MyAppWeb.Router do
use MyAppWeb, :router
pipeline :api do
plug :accepts, ["json"]
end
# localhost:4000/api/{route}
scope "/api", MyAppWeb do
pipe_through :api
get "/random", RandomController, :index
end
end
Custom Controller
As defined in the router, we now need a Controller called RandomController
.
For that, open the folder controllers
(lib/myapp_web/controllers
) and create a new file called random_controller.ex
.
defmodule MyAppWeb.RandomController do
use MyAppWeb, :controller
def index(conn, _params) do
send_resp(conn, 200, "hello world")
end
end
Save this file and now try to start your server.
$ mix phx.server
Your server should be listening on http://localhost:4000/api/random
. Try to enter that URL in your favourite browser. Your should now see "hello world"
😁.
Custom Files
It's not a good practice to write functions directly into your controller - specially in a bigger project - so lets write a helper function that handles everything for us.
Create a folder called helper
with the following path: lib/myapp/helper
.
Since this isn't web related, we will now use our main folder (not the myapp_web
one).
In that folder, create a file called random.ex
.
It should look like this:
defmodule MyApp.Random do
def random_number do
Enum.random(100..10000)
end
end
Awesome, now lets go back to our random_controller.ex
and modify it a little bit.
First of all, import our new helper file with its function.
import MyApp.Random
Then replace our "hello world" response with the function name random_number()
.
Like this:
send_resp(conn, 200, random_number())
.
Your random_controller.ex
should now look like this
defmodule MyAppWeb.RandomController do
use MyAppWeb, :controller
import MyApp.Random
def index(conn, _params) do
send_resp(conn, 200, random_number())
end
end
Save the file and restart your server
$ mix phx.server
Go to the following URL: http://localhost:4000/api/random
, you should now see a random number every time you refresh/enter the page. 🎉
Handling CORS
This is a more in-depth topic - but it's necessary if you want other people to use your API or even call your own APi from another port/ip.
We will use a library called corsica
for this, lets install it by opening our mix.exs
file in the root directory.
Add the following line into your deps
function
{:corsica, "~> 1.2"}
Your mix.exs should now look like this
defmodule MyApp.MixProject do
use Mix.Project
def project do
[
app: :myapp,
version: "0.1.0",
elixir: "~> 1.13",
description: "An example Web APi",
elixirc_paths: elixirc_paths(Mix.env()),
compilers: Mix.compilers(),
start_permanent: Mix.env() == :prod,
aliases: aliases(),
deps: deps(),
author: "github.com/vKxni",
docs: [
main: "readme",
extras: [
"README.md"
]
]
]
end
def application do
[
mod: {MyApp.Application, []},
extra_applications: [:logger, :runtime_tools]
]
end
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
# Here !! :)
defp deps do
[
# phoenix server
{:phoenix, "~> 1.6.10"},
{:telemetry_metrics, "~> 0.6"},
{:telemetry_poller, "~> 1.0"},
{:gettext, "~> 0.18"},
{:plug_cowboy, "~> 2.5"},
{:poison, "~> 5.0"},
{:jason, "~> 1.3"},
# add this line here
{:corsica, "~> 1.2"} # <--
]
end
defp aliases do
[
setup: ["deps.get"]
]
end
end
Once done, run the following command
$ mix deps.get
This might take some time depending on your connection.
Adding CORS to our Endpoint
Open the file called endpoint.exs
in your myapp_web
folder.
(lib/myapp_web/endpoint.exs
)
Now in your Endpoint, add the following lines
plug(Corsica,
max_age: 600,
origins: "*",
allow_headers: ["accept", "content-type", "authorization"],
allow_methods: ["GET", "POST"],
allow_credentials: true,
log: [rejected: :error, invalid: :warn, accepted: :debug]
)
Your endpoint.exs
should now look like this:
defmodule MyAppWeb.Endpoint do
use Phoenix.Endpoint, otp_app: :xadara
@session_options [
store: :cookie,
key: "_myapp_key",
signing_salt: "g10HT1jr"
]
# our CORS config starts here
plug(Corsica,
max_age: 600,
origins: "*",
allow_headers: ["accept", "content-type", "authorization"],
allow_methods: ["GET", "POST"],
allow_credentials: true,
log: [rejected: :error, invalid: :warn, accepted: :debug]
)
# CORS ends here
plug Plug.Static,
at: "/",
from: :myapp,
gzip: false,
only: ~w(assets fonts images favicon.ico robots.txt)
if code_reloading? do
plug Phoenix.CodeReloader
end
plug Plug.RequestId
plug Plug.Telemetry, event_prefix: [:phoenix, :endpoint]
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
json_decoder: Phoenix.json_library()
plug Plug.MethodOverride
plug Plug.Head
plug Plug.Session, @session_options
plug MyAppWeb.Router # this here is important too
end
If something looks a bit different, don't worry, just add the new PLUG right below the session_options
.
And you are done! Congratulations.
Top comments (0)