2016-01-26 2 views
5

Вместо того, чтобы получать данные из базы данных, я хочу использовать в качестве данных вручную написанный файл JSON. Предположим, что мои данные это:Как визуализировать файл JSON с феникс-фреймворком?

[ 
    { "id": 1, "name": "Alice", "email": "[email protected]" }, 
    { "id": 2, "name": "Bob", "email": "[email protected]" }, 
    { "id": 3, "name": "Charles", "email": "[email protected]"} 
] 

и это написано в файле с именем MOCK_DATA.json. Что делать, чтобы отобразить этот файл, когда я обращаюсь к адресу localhost:port/api/v1/users? Как насчет URL-адреса localhost:port/api/v1/users/1, чтобы показать { "id": 1, "name": "Alice", "email": "[email protected]" }?

+1

Итак, вы просто хотите издеваться над ответом, чтобы начать работу быстрее, и заменить его «реальной» реализацией позже? Наверное, это не должно быть готово к производству. –

+0

@PatrickOscity да, точно. –

ответ

9

Вот основной рабочий пример ...

Шаг 1: Создание феникс приложение

например, exjson для ExampleJson или любое имя ваше, как

mix phoenix.new exjson --no-ecto --no-brunch --no-html 
Шаг 2: Настройка маршрутизатора

Добавить эту область для веба/router.ex файла

scope "/api/v1", Exjson do 
    pipe_through :api 
    resources "/users", UserController 
    end 
Шаг 3: Поместите фиктивные данные где-то переменный ток cessible к приложению
priv/data/MOCK_DATA.json 
Шаг 4: Установка UsersController

Придумайте контроллера Users как имеющие ряд действий (функций) где conn struct подается в с вашего феникс конечной точки вместе с любыми параметрами

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 
Шаг 5: Настройка UsersView

Вы также можете думать о пользователях Просмотр в виде имеющих функции, которые будет обрабатывать данные, полученные от контроллера в соответствующим образом. В этом случае вы используете данные json, поэтому phoenix имеет некоторые встроенные функции, которые помогут в этом.

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 
+0

Если вы только отправляете json в свой api, то условия предоставления данных в браузере, часто в наши дни, разработчики используют так называемые рамки Single Page Apps для создания пользовательского интерфейса (компонент браузера). Например, [Aurelia] (http://aurelia.io/), [Angular2] (https://angular.io/), но это просто назвать несколько, их много ... –

+0

Что такое ': code.priv_dir (: exjson) 'в функции' Path.join'? Я искал исходный код phoenix, но мой поиск оказался пустым. –

+1

Это функция из библиотеки [erlang] (http://erlang.org/doc/man/code.html#priv_dir-1) .. она просто получает вашу личную папку. Файлы в этой папке доступны для приложения. –

1

Если файл является статическим (не изменяется для хода выполнения службы), вы можете прочитать его, когда приложение будет компилироваться в вашем контроллере. Изучите параметры модуля (те, которые вы определяете в своем модуле, вне функций). Таким образом, я буду разбираться один раз.

Если этот файл является динамическим, вам может потребоваться его прочитать при каждом вызове API и его анализе. Не рекомендуется, так как чтение файла с диска IO замедлит его.

В любом случае результат файла, разобранный на карту, может быть передан в представление и визуализирован, без различия с базой данных.

Редактировать: еще одно предложение - переформатировать ваш JSON (если возможно) и иметь id в качестве ключа, а остальные данные в качестве значения. Таким образом, поиск по id будет очень быстрым, точно так же, как индекс первичного ключа в базе данных.

+0

Я новичок, как в Финиксе, так и в Эликсире, поэтому я не понял вашего ответа. Не могли бы вы привести несколько примеров кода? Кроме того, спасибо за рекомендации по производительности, но на данный момент я даже не знаю, как отображать данные в браузере, поэтому я хотел бы получить конкретные инструкции по этой области. –

8

Чтобы дать вам некоторый реальный код, чтобы начать работу, это самое простое, что я могу думать:

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 

Тогда просто сохранить свои поддельные данные в priv/mock_data/users.json внутри вашего проекта. Там могут быть опечатки, но вы получаете основную идею ...

2

Поскольку вы просто эхо отзываете JSON на конечную точку /users, в этом случае вам не нужен вызов Poison.decode/1, который делает ненужное декодирование/кодирование JSON.

Таким образом, адаптация кода Патрика:

defmodule MyApp.UserController do 
    @mock_data_string (
    Application.app_dir(:my_app, "priv/mock_data/users.json") 
    |> File.read! 
) 

    def index(conn, _params) do 
    conn 
    |> put_resp_content_type("application/json") 
    |> send_resp(200, @mock_data_string) 
    end 
end 

Однако для /users/1 конечной точки, то лучше всего для извлечения значений с помощью Poison.decode/1, а @ stephen_m Ответим иллюстрирует.

+0

Это хорошо! Мне просто нужно что-то подобное (просто пересылка данных JSON с другого сервера через Phoenix). Я попробую! – fenton

Смежные вопросы