There are a few guides which cover combining Phoenix and React.js, but they all seem to assume a certain level of knowledge about the javascript ecosystem, or use a particular combination of magical build tools.
I like to build up from scratch, whenever I can. Otherwise, I don’t feel like I really understand what’s going on. So, I set out to build a web application that uses Phoenix to serve a JSON API, and a React.js single page application to consume it.
Our application will be a bookshelf manager, which allows you to manage a collection of books. Initially, all we’re going to do is store a list of books and render a list page with all the books on it, and a show page for a single book.
Pre-requisites
You will need the following tools installed locally;
Let’s get started.
Create the Phoenix application
mix phoenix.new bookshelf --no-brunch --database mysql
Enter “y” when prompted to Fetch and install dependencies? [Yn]
There are other options for the database. I’m just using mysql because I already have it installed, and I’m more familiar with it. Run mix help phoenix.new
to find out the various options.
We won’t be using the default Brunch build tool, hence the --no-brunch
flag.
That creates the skeleton of our application. Now create the database;
cd bookshelf
mix ecto.create
We’ll need a Book
model. We’ll start with just a title, author, and the URL of a cover image;
mix phoenix.gen.json Book books title:string author:string cover_image_url:string
Using phoenix.gen.json
indicates that we only want a JSON API for this resource, so we won’t get HTML views. You should see the following output;
* creating web/controllers/book_controller.ex
* creating web/views/book_view.ex
* creating test/controllers/book_controller_test.exs
* creating web/views/changeset_view.ex
* creating priv/repo/migrations/20151220100520_create_book.exs
* creating web/models/book.ex
* creating test/models/book_test.exs
Add the resource to your api scope in web/router.ex:
resources "/books", BookController, except: [:new, :edit]
Remember to update your repository by running migrations:
$ mix ecto.migrate
As per the prompts, edit the web/router.ex
file, uncomment the api scope and add the resource;
Then run the migration to create the books table;
mix ecto.migrate
Let’s add some seed data, so we’ve got something to work with.
Edit priv/repo/seeds.exs
and add the following content;
Run the script to add the data to our development database;
mix run priv/repo/seeds.exs
Now, we should have a working JSON API. Let’s test it. First, start the application;
mix phoenix.server
Now, in another terminal, let’s make a call to get the list of books;
curl http://localhost:4000/api/books | python -m json.tool
The ` | python -m json.tool` is just a JSON pretty-printer. Leave it out if you don’t have it installed. |
This should give us the following output;
So, the list call works. How about the show
call, to get data for a single book?
curl http://localhost:4000/api/books/1 | python -m json.tool
This should produce;
OK, so now we have a working, if basic, API backend.
In the next part of this series, we’ll look at the more interesting part - building a React.js frontend.