falcor-router icon indicating copy to clipboard operation
falcor-router copied to clipboard

Returning ref values for leaf properties

Open noonian opened this issue 9 years ago • 7 comments

Hello. I'm not sure if this is a bug or not.

I was hoping I could model a resource with a specific prop being a reference to a specific prop of a different resource. In my data model this happens occasionally where ids that are really refs to resources are 'mapped' to just the email of the linked resource for example.

Given a router defined with the routes below, the router will return the ref array as if it was a primitive value for the resource at path ['thing', 'refProp'].

[
      {
        route: ['thing', 'refProp'],
        get: function (path) {
          return {
            path: ['thing', 'refProp'],
            value: $ref(['otherThing', 'prop'])
          }
        }
      },
      {
        route: ['otherThing', 'prop'],
        get: function (path) {
          return {
            path: ['otherThing', 'prop'],
            value: 'some value'
          }
        }
      }
    ]

With this call from the browser model:

var model = new falcor.Model({source: new falcor.HttpDataSource('/model.json') });
model.get(['thing', 'refProp']).then(function (res) { console.log(res); });

The router will return this payload instead of traversing the reference:

{
  "jsonGraph": {
    "thing": {
      "refProp": {
        "$type": "ref",
        "value": ["otherThing","prop"]
      }
    }
  }
}

And the falcor model on the client will convert that to this:

{
  "json": {
    "thing": {
      "refProp": ["otherThing","prop"]
    }
  }
}

This seems like a useful usecase to me, but please correct my thinking if not supporting this is by design.

If this is a bug, I believe it stems from this line: https://github.com/Netflix/falcor-router/blob/master/src/run/recurseMatchAndExecute.js#L78

Since suffix.length will always be 0 in this case, the ref path will never be expanded/followed.

noonian avatar Sep 10 '15 17:09 noonian

This is expected behavior. Falcor only follows references if you attempt to look up a key on those references. Otherwise it returns the reference itself. The reason why this is useful behavior is that you may want to simply preload references without loading their targets. This allows you to make an optimized request later on for the targets of the references, because Falcor will use the references to retrieve the data more efficiently.

JH

On Sep 10, 2015, at 10:30 AM, Jed Clinger [email protected] wrote:

Hello. I'm not sure if this is a bug or not.

I was hoping I could model a resource with a specific prop being a reference to a specific prop of a different resource. In my data model this happens occasionally where ids that are really refs to resources are 'mapped' to just the email of the linked resource for example.

Given a router defined with the routes below, the router will return the ref array as if it was a primitive value for the resource at path ['thing', 'refProp'].

[ { route: ['thing', 'refProp'], get: function (path) { return { path: ['thing', 'refProp'], value: $ref(['otherThing', 'prop']) } } }, { route: ['otherThing', 'prop'], get: function (path) { return { path: ['otherThing', 'prop'], value: 'some value' } } } ]

With this call from the browser model:

var model = new falcor.Model({source: new falcor.HttpDataSource('/model.json') }); model.get(['thing', 'refProp']).then(function (res) { console.log(res); });

The router will return this payload instead of traversing the reference:

{ "jsonGraph": { "thing": { "refProp": { "$type": "ref", "value": ["otherThing","prop"] } } } }

And the falcor model on the client will convert that to this:

{ "json": { "thing": { "refProp": ["otherThing","prop"] } } }

This seems like a useful usecase to me, but please correct my thinking if not supporting this is by design.

If this is a bug, I believe it stems from this line: https://github.com/Netflix/falcor-router/blob/master/src/run/recurseMatchAndExecute.js#L78

Since suffix.length will always be 0 in this case, the ref path will never be expanded/followed.

— Reply to this email directly or view it on GitHub https://github.com/Netflix/falcor-router/issues/132.

You received this message because you are subscribed to the Google Groups "Falcor" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. To view this discussion on the web visit https://groups.google.com/a/netflix.com/d/msgid/falcor/Netflix/falcor-router/issues/132%40github.com https://groups.google.com/a/netflix.com/d/msgid/falcor/Netflix/falcor-router/issues/132%40github.com?utm_medium=email&utm_source=footer .

falcor-build avatar Sep 10 '15 19:09 falcor-build

@noonian if you want to retrieve the value beyond the reference, you can add null to the end of your original request:

// With 'null' at the end of the path, the router will see 'refProp'
// as a "branch" key. If 'refProp' is a reference, it'll be followed.
// If it's a value, path-resolution will short-circuit at the value
// and 'null' will be ignored.

var model = new falcor.Model({source: new falcor.HttpDataSource('/model.json') });
model
  .get(['thing', 'refProp', null])
  .then((res) => {
    console.log(res);
  });

trxcllnt avatar Sep 10 '15 21:09 trxcllnt

Ah I see, that makes sense. Thanks for the explanation.

noonian avatar Sep 10 '15 21:09 noonian

One of the reasons we have a documented this feature yet is that we are not certain if it is generally useful to have references to values. In practice it doesn't seem to happen very often. Please just be aware that this is an undocumented feature that may be removed in the future.

JH

On Sep 10, 2015, at 2:33 PM, Jed Clinger [email protected] wrote:

Ah I see, that makes sense. Thanks for the explanation.

— Reply to this email directly or view it on GitHub https://github.com/Netflix/falcor-router/issues/132#issuecomment-139385617 .

You received this message because you are subscribed to the Google Groups "Falcor" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. To view this discussion on the web visit https://groups.google.com/a/netflix.com/d/msgid/falcor/Netflix/falcor-router/issues/132/139385617%40github.com https://groups.google.com/a/netflix.com/d/msgid/falcor/Netflix/falcor-router/issues/132/139385617%40github.com?utm_medium=email&utm_source=footer .

falcor-build avatar Sep 10 '15 21:09 falcor-build

I ran into this need also: https://github.com/Netflix/falcor-router/issues/175 I closed the issue, but referencing it here for posterity.

greim avatar Feb 24 '16 00:02 greim

What about making it so when you request a path to a reference, it could behave conditionally?

  1. If another route matches the reference, follow it and resolve the new route.
  2. Otherwise, return the reference as the value directly, as it does currently.

That's how I assumed it would work based on everything I tried up to now, actually. The reason it would be nice to be able to alias leaf nodes like this is it would avoid some round tripping in my scenario. Can show examples if needed.

greim avatar Feb 24 '16 01:02 greim

@greim you're right. since the router has full knowledge of all valid paths, it could make this distinction. need buy-in from @jhusain and @michaelbpaulson. I know they've got a lot on their plates.

trxcllnt avatar Feb 25 '16 06:02 trxcllnt