When to add Ember Data


#1

This post is a followup to some discussions in Slack with Learning Team people. I wrote:

Hypothesis: we should stop trying to teach routing and ember-data simultaneously. They are separate topics and each is complex enough by itself that mashing them together leads to a lot of confusion. I’m speaking specifically about places like here. People are often amazed when I point out that they can just use fetch or jQuery.ajax or anything else they already understand.

And we had a lot of general agreement. There was a followup question that I thought deserves a more thorough response, which is: what is the rationale for when you should choose Ember Data?

There is certainly nothing wrong with just always starting with Ember Data, and that is why it’s in the default app blueprint. But I frequently see questions from beginners who are struggling because they have found a use case where it’s not obvious how to make Ember Data do something, and they’re not even aware that they can simply bypass it and do a simpler thing. When you’re already busy learning routing and components and services, it’s pretty nice to just fetch some JSON and delay learning about models and adapters and serializers until you actually need those things.

So when do you need those things? It comes down to a few dimensions:

  • the more concurrent, interactive reading and writing your app does, the more you will benefit from having Ember Data’s identity map. Apps that mostly just read data are easier to keep consistent, so they don’t benefit as much.
  • as the number of different kinds of data (models) in your application grows, you’ll start to benefit more from standardizing how they’re all defined, loaded, and saved. At a certain scale, having fetch sprinkled throughout your codebase makes it pretty hard to even know where all the data is coming from.

I think an ideal way to teach these areas is to start without Ember Data, and point out the missing features in the app (caching, identity mapping, shared code for translating to and from the server formats, etc), and start implementing some of these features directly so the learner understands what they are for, and then switch to Ember Data and delete a bunch of code.


#2

A followup: I have also heard “does your server support JSON:API”? as a reason to choose or not choose Ember Data. I think it’s a bit more nuanced than that.

If your server does, then you will go further before you need to learn about advanced Ember Data topics like customized serializers and adapters. That lowers the cost of adopting Ember Data, so it does help tip you toward adoption.

If your server doesn’t, Ember Data may still be extremely helpful. It may be even more helpful, because without something like Ember Data you will have a lot of idiosyncratic code for understanding weird and diverse server endpoints spread throughout your app, instead of all neatly packaged away inside adapters. But it’s true that this means you will need to learn more about Ember Data earlier in the process, so the investment in learning is moved more up front.


#3

Some great points here, just the thing I was looking for as I have often contemplated the benefits of Ember Data and wasn’t sure that I was fully understanding what it offered and when it would pay big dividends.


#4

Very much agree to this.

I always look into why people keep on saying that Vue is super easy. I’ve come to the conclusion that it’s just as easy as React and Ember. Vue just has a well defined docs that simplifies things and introduces extra stuff (Vue Router, Vuex, etc.) at the right time. Maybe we can learn and adopt something from them since it’s so well received by a lot of people.


#5

It’s not only about “how to do it with Ember Data”. I’ve often seen developers fighting Ember Data cause they try to use it for all API requests. Especially firing API actions is such an issue. A good example is this question on Stackoverflow. Obviously the developer tries to fire a API action to send a code. To achieve that with Ember Data, a sendCode model is created, which holds the payload. The action creates a record of that model, fires the action using save method and then unloads the record from store… Said that, I agree very much that the guides should make it more clear what Ember Data is meant for.


#6

One thing I’d say is that serializers and adapters is probably an area where documentation can be improved. Better explanations and examples would help demystify these two areas and make them more approachable.

This is one of the places I tend to find myself diving into source code to find the answer to a question. I don’t have specific examples off the top of my head, but I’ll try to come back to this thread with more specifics when I run into them (non JSON:API standard API means I end up in these fairly often). If I can, I’ll try to contribute better documentation, I just haven’t felt like I knew enough in the past to be effective.


#7

Most of my models are physics models driven by a cascade of computed values rather than data models stored in a database. Where I do have stored persistent data, most of it is in the form of trees, not tables, and where I have table data, it doesn’t reside in databases.Most of my data interactions are simple enough that a service that orchestrates fetches seems to be adequate. I’d love to use Ember Data, but it never seems to fit.

However, recently, there was this one app… I was briefly flirting with Firebase and emberfire for storage. This app could have been a good match for Ember Data, but when a hasMany().reload of a subtree of my data turned up an array of zero objects for no apparent reason, I found the framework documentation provided no clue on how to begin to debug an outcome like this, or even to determine if the “signal” was getting lost in ember-data, in emberfire, or in Firebase. With no hard data, what would I even ask? And where? Nobody can usefully answer a question that isn’t concrete, except with a series of steps to take to come back with a more concrete question.

The guides do a reasonable job at describing how to write an ember-data interface. What I couldn’t find is a debugging fast-track for the 90% of ember-data’s potential users who pick up ember-data, a suitable plug-in, perhaps a JSON:API module for their server platform, install them all using the commands in their READMEs, and try to use them out of the box, praying they’ll “just work” and they can pick up their data and use it.

Right now, the user must either walk through the framework in search of their missing data, digging in to learn all those details from which they were hoping the abstraction would protect them - or they try things until something happens to work, make up stories about why, and tell the stories to all their friends and neighbors on the web.

What we need from those who already know the territory are a set of test points we can quickly attach to, in a “divide-and-conquer” strategy, to find out generally whether our data arrived or left at all, and what county it was in when it disappeared. We need an indication of how to find the test points, what to examine at each test point and what general sort of thing to expect when we look there. It needs to be told in such a way as to be useful to somebody who is looking at somebody else’s code for the first time.

With this level of guidance, we can focus our learning on the actual source of the problem, have more fruitful support discussions on the web, and - perhaps :wink: - fewer inaccurate rumors.


#8

Totally agree.

  1. Start with plain json for the routes story
  2. Start the Ember Data story with a question, listing all source options, then let the user follow the happy path

#9

I think there’s a big push of “use Ember Data only if your API uses JSON:API” for small projects I think this is fairly reasonable.

Really I would say use Ember Data for resources/data sources with some sort of standardization or predictability and description. For new APIs I would heavily recommend JSON:API since it works out of the box. But, if you have a legacy API with good standardization and serialization then making an Ember Data adapter makes sense (for instance if you have 100s of models using Active Model Serializer, using a single adapter for all those resources makes a lot more sense than not using Ember Data or rewriting to JSON:API).

On the flip side though. If you don’t need caching or deduping or background loading, you may want to use fetch or a simple AJAX wrapper to avoid the weight and cost of Ember Data models (observers, etc). For instance for reporting we use AJAX or fetch with POJOs and Map/Reduce functions even though our reporting APIs are all JSON:API because we don’t need to have model tracking.


I like Ember a lot, But I'm Worried
#10

As someone who’s trying to learn Ember & struggling with ember data, I agree with most of what’s said here. I’ve tried to take the ‘high road’ and use ember data from the start. During that early phase, I got my butt kicked and failed to get anything built.

If not for people on this forum encouraging me (more than once) to essentially ignore the official how-to docs and start with jQuery to load data, I’d have walked away from ember.

I found lots of ember data tutorials out there. But most of them use either mock data or Firebase for the back end. This makes them pretty much useless for learning anything but the most basic concepts. The other tutorial approach I see is: Step one: build a backend in Ruby! Unless you’re a ruby dev already, this just adds to the frustration. The third approach: JSON:API. I’ve honestly never seen a spec compliant json api at any company I’ve worked at. Again, for me personally not very helpful.

I spent days trying to find an ember data tutorial that loaded real data from a real less-than-perfect REST API. This blew my mind, because in most web dev tutorials, step one is “get the data”.

The best resource I’ve found to learn ember data: Scott Batson’s excellent Ember tutorials on YouTube. Thank god for these!

As for sample apps on the guides page - who says there can only be one? Why not have three:

  1. Basic concepts
  2. Load data first with jQuery, then with Firebase
  3. Load data with JSON adapter, AND DS.RESTAdapter

Also, it would be nice to show people how to load a list of data and to load a single item.


#11

I’ve actually always wondered why ember-data didn’t support actions like this? Why couldn’t an adapter define a custom action (maybe a method on an actions object) and then all models of that type gain a method on them which performs the correct API and uses the response to update the model…

Oh wait we can already do this with fetch or ember-ajax Just add a method on the model itself and do the thing you want to do. Hmm. maybe this is to nuanced to have an addon scoped solution.


#12

That’s actually exactly where we (the Learning Team) intend to take the guides, for just the reasons you’ve mentioned. Sadly, open source tutorials have a way of taking a while to get done …

Sorry to hear about the headaches, but glad to hear you’ve figured out how to load data as best suits you!


#13

Or you can use an addon like ember-api-actions