Instead of fetching data from a database, I want to use as data a manually written JSON file. Suppose my data is this:
[
{ "id": 1, "name": "Alice", "email": "[email protected]" },
{ "id": 2, "name": "Bob", "email": "bob@example" },
{ "id": 3, "name": "Charles", "email": "[email protected]"}
]
and it's written in a file called MOCK_DATA.json
. What should I do to render this file when I access the localhost:port/api/v1/users
url? How about the localhost:port/api/v1/users/1
url to show { "id": 1, "name": "Alice", "email": "[email protected]" }
?
Here is a basic working example...
Step 1: Create the phoenix appeg, exjson for ExampleJson or whatever name your like
mix phoenix.new exjson --no-ecto --no-brunch --no-html
Step 2: Set up the router
Add this scope to the web/router.ex file
scope "/api/v1", Exjson do
pipe_through :api
resources "/users", UserController
end
Step 3: Put the mock data somewhere accessible to the app
priv/data/MOCK_DATA.json
Step 4: Set up the UsersController
Think of the Users Controller as having a number of actions (functions) where the conn struct is fed into from your phoenix endpoint along with any parameters
defmodule Exjson.UserController do
use Exjson.Web, :controller
# GET http://localhost:4000/api/v1/users/
def index(conn, _params) do
users = File.read!(file) |> Poison.decode!()
render conn, users: users
end
# GET http://localhost:4000/api/v1/users/1
def show(conn, params) do
users = File.read!(file) |> Poison.decode!()
render conn, user: users |> Enum.find(&(&1["id"] === String.to_integer(params["id"])))
end
defp file() do
Path.join(:code.priv_dir(:exjson), "data/MOCK_DATA.json")
end
end
Step 5: Set up the UsersView
You can also think of the Users View as having functions that will render the data received from the Controller in the appropriate way. In this case, you are using json data so phoenix has some built in functions to help with that.
defmodule Exjson.UserView do
use Exjson.Web, :view
def render("index.json", %{users: users}) do
render_many(users, __MODULE__, "user.json")
end
def render("show.json", %{user: user}) do
render_one(user, __MODULE__, "user.json")
end
def render("user.json", %{user: user}) do
%{
id: user["id"],
name: user["name"],
email: user["email"]
}
end
end
To give you some real code to get started, this is the simplest thing I can think of:
defmodule MyApp.UserController do
@mock_data (
Application.app_dir(:my_app, "priv/mock_data/users.json")
|> File.read!
|> Poison.decode!
)
def index(conn, _params) do
conn
|> put_status(:ok)
|> json(@mock_data)
end
end
Then just save your fake data in priv/mock_data/users.json
inside your project. There might be typos in there, but you get the basic idea...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With