Lesson 14

Consuming the REST API


⚠️ This tutorial uses an old version of Ember. Some things might have changed!

Ember Data's REST conventions

Before we go on with our app, it's important to understand that by using Ember Data, we're buying into Ember's conventions on how your REST API should behave.

In our case, the conventions are pretty much handled automatically since we're using November, but it's important to be aware of these when making changes to your data-driven app.

Let's look at the conventions you need to know about for a basic CRUD (Create, Read, Update, Delete) app. If you don't know about these already, you should learn them:

Finding records

There are 3 ways to find records: finding all, finding from a query and finding by id.

Find all records:

Triggered by: store.findAll('user')

Sent request: GET /users/

GET /users

Find a record from an id:

Triggered by: store.findRecord('user', 1)

Sent request: GET /users/1

Find record(s) from a query:

Triggered by: store.query('user', { name: 'Bob' })

Sent request: GET /users?name=Bob

GET /users?name=Bob

Creating records

Triggered by: store.createRecord('user', {...}).save()

Sent request: POST /users (with a request body containing a user object)

POST /users/

Updating records

Triggered by:

Sent request: PUT /users/1 with a request body containing the updated user object

PUT /users/1

Deleting records

Triggered by:

Sent request: DELETE /users/1

DELETE /users/1

Replacing our fixtures

Now that you have an idea of how it works, let's edit our RESTAdapter so that, instead of consuming the Mirage fixtures, it makes API calls to our November server (make sure you still have November running in the background)!

We'll start by adding the backend's domain as an environment variable in our Ember app. We use an environment variable for this because once we run our site in production, the URL won't be localhost:9000 anymore. We also specify that we want ember-cli-mirage to be disabled now.


Next, in our adapter-file, we import our environment variables at the top of it, then set the host to our apiURL variable (you can remove the prefix we used earlier).


You might notice now that if you go back to your Chirper app's "home"-page in the browser, the page becomes blank (uh-oh). If you bring up the JavaScript Console, you should see this error message:

This is one of the error messages you should see.

Although it's an error, this is actually a good sign. The data that we request in our home route is no longer fetched from the fixtures, but our Ember app attempts to get it from localhost:9000 (where our November app resides) when it runs this.store.findRecord('user', 1)

As you can see, the correct request was triggered (GET /users/1), but our API returned an error. This is because we haven't yet created any user with id 1 in our MySQL database yet, so let's do that!

Note: You can also use a GUI tool like Sequel Pro to visualize and manipulate your database tables if raw SQL queries scare you. ?

While we're at it, let's also add the first chirp to our database.

Refresh the page and... it's alive!

Now, there's one more error in our console that we should fix, namely the violation of the Content Security Policy:

This error might seem strange at first since our data is loading after all and everything seems to work well. This is because we're still in development mode, so the errors show up but they don't actually break the app. Nevertheless, you should consider using CSP when deploying your app though, as it protects against nasty XSS-attacks.

Anyway, let's get rid of that error by adding just 3 lines of code in our config file, where we explicitly allow the our app to make AJAX requests to localhost:9000:


Errors be gone! And that's how easy it is to convert your app from using fixture data for prototyping, to using real data from an actual database!

You should now be able to navigate around all your pages in the app without getting any errors.

A new bug has appeared though: if you try posting a new chirp, you'll notice that the POST request returns an error and the chirp isn't saved in the database. This will be fixed in the next chapter, where we fetch the logged-in user in our November app through token authentication.



in my configuration.js there's a rootURL but no baseURL

Tristan Edwards

@ludu-co: Correct! "baseURL" was deprecated in Ember 2.7. Thanks for the reminder, I've updated the course!

Visva DevWorks

Is this insert really working without specifying the id of the chirp?

I am using Postgres, but I assume the model would be the same.

Tristan Edwards

@visvadevworks: Yes, the id-field is auto_increment by default, so it will be set automatically. :)

Hertanu Sabin

The content security policy link should be http://www.ember-cli.com/user-guide/#deployments

Bill Pullen

is there any reason to reopen rather than extend here