DEV Community

Cover image for Connecting Ember.js with Phoenix
Kevin Expósito
Kevin Expósito

Posted on • Edited on

Connecting Ember.js with Phoenix

Introduction

The aim of this article is not only to show how to connect a backend application using Phoenix and a frontend application using Ember, but also to know all the different issues that may be encountered when trying to connect any frontend or backend application.

Versions used in this guide:

Elixir: 1.11.3
Erlang/OTP: 21
Phoenix: 1.5.7

Node: 12.13.0
Ember CLI: 3.24.0
Enter fullscreen mode Exit fullscreen mode

Creating Phoenix backend

Let's start by creating our project in Phoenix by running the following command:

$ mix phx.new pizza_corner_api
(...)
$ cd pizza_corner_api
$ mix ecto.create
$ iex -S mix phx.server
Enter fullscreen mode Exit fullscreen mode

Then, let's create a migration in our application:

$ mix phx.gen.schema Api.Pizza pizzas name:string description:text image:string
Enter fullscreen mode Exit fullscreen mode

This will generate the following files:

Now, we are going to apply the migration by running:

$ mix ecto.migrate
Enter fullscreen mode Exit fullscreen mode

Nice! we have the Pizza table created, let's add some seeds:



After this, run:

$ mix run priv/repo/seeds.exs
Enter fullscreen mode Exit fullscreen mode

Returning JSON API Responses with JaSerializer

Now we are almost ready to create the PizzaController and router, but before doing that, let's think about what we are doing. We are building the frontend in Ember and the backend in Phoenix. These technologies must communicate with each other. To do this we are going to use JSON API. This means that Phoenix and Ember apps must send and receive JSONAPI responses.

To do this in Phoenix we are going to use JaSerializer (https://github.com/vt-elixir/ja_serializer).

Installing JaSerializer

# mix.exs
defp deps do
    ...
    {:ja_serializer, "~> 0.16.0"},
    {:poison, "~> 3.1"}
    ...
end
Enter fullscreen mode Exit fullscreen mode
$ mix deps.get
Enter fullscreen mode Exit fullscreen mode
# config.exs
config :phoenix, :format_encoders,
  "json-api": Poison

config :mime, :types, %{
  "application/vnd.api+json" => ["json-api"]
}
Enter fullscreen mode Exit fullscreen mode

And then:

$ mix deps.clean mime --build
$ mix deps.get
Enter fullscreen mode Exit fullscreen mode
# router.ex
pipeline :api do
  plug :accepts, ["json-api"]
  plug JaSerializer.ContentTypeNegotiation
  plug JaSerializer.Deserializer
end
Enter fullscreen mode Exit fullscreen mode

Finally, we are going to create the Pizza View and Controller:

Don't forget to add the endpoint to the router!

# router.ex
scope "/api", PizzaCornerApiWeb do
  pipe_through :api

  get "/pizzas", PizzaController, :index
end
Enter fullscreen mode Exit fullscreen mode

Creating the Ember frontend

$ ember new pizza_corner --no-welcome
Enter fullscreen mode Exit fullscreen mode

Adding the Pizza Model



Now, lets run the following code to see if everything is working fine:

$ ember s
Enter fullscreen mode Exit fullscreen mode

and check it http://localhost:4200

What is happening?

If we open the console, we will see something like this:
Alt Text
What does this mean? By default Ember will request the same URL it is running on, so we must specify that we want to hit our Phoenix backend. To do this, we have to override the adapter as follows:

host is the url that we want to hit, and namespace is the path after the host. This is because, in the Phoenix router we specified that pizzas are inside api scope. By doing this and thanks to Ember JSONAPIAdapter, store.findAll('pizza') will hit http://localhost:4000/api/pizzas . To see more about this you can see: https://api.emberjs.com/ember-data/release/classes/JSONAPIAdapter

Update your app/serializers/application.js:

Now, let's try again, hopefully we will see some magic.
And no magic happens, So.. lets see the inspector again 😡
Alt Text

We are having a CORS issue here. Why does this happens?

This happens because of security. CORS doesn't allow communication between our Ember web app (http://localhost:4200) and our Phoenix api (http://localhost:4000) because they are not from the same path and this is not safe.

What can we do to fix this?

In order to fix this, we should tell our Phoenix API to accept incoming requests from Ember. To do this, we will use CORS Plug https://github.com/mschae/cors_plug, this plugin will allow us to configure that.

Installing CORS Plug

# mix.exs
defp deps do
    ...
    {:cors_plug, "~> 2.0"},
    ...
end
Enter fullscreen mode Exit fullscreen mode

And then run:

$ mix deps.get
Enter fullscreen mode Exit fullscreen mode

Also add:

#lib/pizza_corner_api_web/endpoint.ex
defmodule PizzaCornerApiWeb.Endpoint do
  use Phoenix.Endpoint, otp_app: :pizza_corner_api
    ...
    ...
    plug CORSPlug, origin: ["http://localhost:4200"] # <- Add this
    plug PizzaCornerApiWeb.Router
end
Enter fullscreen mode Exit fullscreen mode

And after this, restart the server:

$ mix phx.server
Enter fullscreen mode Exit fullscreen mode

Now visit http://localhost:4200 one more time. You will see the pizzas from our backend being rendered! 🎉🎉🍕

Alt Text
Phoenix Documentation:

Ember Documentation:

Things we used here:

Top comments (3)

Collapse
 
charlesfries profile image
Charles Fries

TIL --no-welcome is a thing, thank you sir

Collapse
 
madza profile image
Madza

Phoenix!? Time to search it up 😄😄

Collapse
 
santiago_veiga_53b2edaf0e profile image
Santiago Veiga

very helpful!