Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full object graph always requested? #40

Open
jc00ke opened this issue Aug 10, 2016 · 14 comments
Open

Full object graph always requested? #40

jc00ke opened this issue Aug 10, 2016 · 14 comments

Comments

@jc00ke
Copy link

jc00ke commented Aug 10, 2016

We're seeing that all of the relationships are passed through, which doesn't seem like it jives with GraphQL as a "only what the client needs" query language.

Is there a way I'm not seeing, or plans to be able, to specify which fields should be returned?

Thanks!

@daemonsy
Copy link

Hey @jc00ke thanks for reporting this. Just to be sure we're talking about the same thing, is your use case regarding partial field selections?

For example, a blog post has an author and your page only needs the name of the author, so there's no need to load any of the other fields?

Currently the adapter doesn't support this, it always loads the full model. Will be looking into this but I have no idea how hard this is at this point.

@jc00ke
Copy link
Author

jc00ke commented Aug 12, 2016

Yes, that's exactly the scenario.

@dustinfarris
Copy link

My guess is that this will be an ember-data limitation more than with this adapter. Last time I checked, ED does not handle partial record loading well.

I've been toying with the idea of using a separate store, like redux, for data loaded with GraphQL.

@jc00ke
Copy link
Author

jc00ke commented Oct 10, 2016

@dustinfarris I'm not familiar with how Ember Data works, but are you saying that if a Post has an Author that the Author will always be requested? Or that it'll be fetched when you post.author?

@daemonsy
Copy link

Hey @jc00ke I'm guessing what @dustinfarris mean was more like if the view uses author.name and author.email only, ember data normally fetches all attributes for the author model above the name and email attribute

@dustinfarris
Copy link

Yes, what @daemonsy said. ED is sort of "all or nothing" when it comes to loading a model. There is an addon that tries to work around this, ember-data-partial-model, but I'm not a big fan of the API

I am working on a new addon to leverage GraphQL (via cashay) using redux as the store, instead of Ember Data. See my thoughts here: mattkrick/cashay#120

@jc00ke
Copy link
Author

jc00ke commented Oct 12, 2016

Cool, OK. I get that ED will load a complete model, but how does it handle associations? I'm assuming it won't start traversing the tree.

Thanks for the clarification!

@bgentry
Copy link

bgentry commented Oct 22, 2016

I was giving this addon a try on a new app I'm proofing out. The data is modeled as 3 types with hasMany relationships:

Zone -> Device -> Sensor

Zones have many devices, and device have many sensors.

When loading the top-level route for a Device, my GraphQL adapter sent the following query (prettified):

query device {
  device(id: "7ecbefe0-dd8c-4345-bdd9-34b85cb65515") {
    id
    name
    zone {
      id
      name
      devices {
        id
        name
        sensors {
          id
          kind
          description
        }
      }
    }
  }
}

So on a page that's just rendering some data about the device, the adapter asked for data about the device's parent zone (good) as well as all of that zone's associated devices (bad) as well as all those devices' sensors.

Unfortunately that makes the addon practically unusable with any real amount of data for this common scenario of 3 related types.

What I actually want is this query:

query device {
  device(id: "7ecbefe0-dd8c-4345-bdd9-34b85cb65515") {
    id
    name
    sensors {
      id
      kind
      description
    }
    zone {
      id
      name
    }
  }
}

I realize a lot of the limitations are a result of ember-data, but I'm thinking there must still be a better option. With a JSON API, Ember-data uses a promise for unresolved relationships that come in as links in the serialized response. Maybe this addon can do something similar where hasMany relationships aren't resolved until they're requested (or only IDs are requested in the query)?

I tried using async: true on one of these hasMany relationships which didn't work because it messed up the name of the ID field. Here's a query for a zone that shows sensorIds instead of what should be sensors { id }:

query zone {
  zone(id: "f312fa4c-5328-4145-b210-0a0df18dd827") {
    id
    name
    devices {
      id
      name
      sensorIds
    }
  }
}

I guess that's a different bug though.

@delkopiso
Copy link
Contributor

@bgentry the adapter currently doesn't do anything to figure out what structure you want. I just interprets the model structure you've defined via Ember Data.

For example with this structure:

// app/models/zone.js
export default DS.Model.extend({
  name: DS.attr('string'),
  devices: DS.hasMany('device'),
});

// app/models/device.js
export default DS.Model.extend({
  name: DS.attr('string'),
  zone: DS.belongsTo('zone'),
  sensors: DS.hasMany('sensor'),
});

// app/models/sensor.js
export default DS.Model.extend({
  kind: DS.attr('string'),
  description: DS.attr('string'),
  device: DS.belongsTo('device'),
});

There is currently no way for the adapter to know that it should ask for name and not devices when zone is being retrieved as a selection set of device, but ask for both when zone is the top level node. At least not without the introduction of some extra DSL. We've worked around this by using async: true like you've tried.

Regarding sensorIds vs. sensors { id }, the problem here is that Ember Data only wants to deal with JSON API data. So when a model's relationship is async it expects a relationship_id attribute in the payload.

@bgentry
Copy link

bgentry commented Feb 1, 2017

@delkopiso thanks for the reply. I've come to the conclusion that graphql and ember-data aren't a very good fit for each other due to mismatched expectations. I settled on using Apollo Client with ember-apollo-client, and some are using @dustinfarris' ember-cachay.

Thanks for your work building out this addon nonetheless! It helped inspire me to make the jump into GraphQL.

@delkopiso
Copy link
Contributor

No worries. I like what you done with ember-apollo-client!

@steffansluis
Copy link

Hey! I've started using ember-graphql-adapter recently and I have to say, I like it a lot. During some reading, I came across this part of the Ember Data docs, which seems to offer a way of accomplishing the goal of this issue by specifying what relationships to include via the adapter:

import Ember from 'ember';

export default Ember.Route.extend({
  model: function() {
   return this.store.findAll('post', {include: 'comments'});
  }
});

Just wanted to drop that information here.

@viniciussbs
Copy link

@steffansluis Functions to fetch collections have this options that you mentioned, but functions like find don't.

@steffansluis
Copy link

steffansluis commented Mar 17, 2017

@viniciussbs In Ember Data 2.5, findRecord does have this option (although to be fair, I didn't know that either until I looked it up just now).

Edit: Still seems to be the case for Ember Data 2.11

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants