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

Returning ref values for leaf properties #132

Open
noonian opened this issue Sep 10, 2015 · 7 comments
Open

Returning ref values for leaf properties #132

noonian opened this issue Sep 10, 2015 · 7 comments

Comments

@noonian
Copy link

noonian commented Sep 10, 2015

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.

@falcor-build
Copy link
Contributor

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 notifications@github.com 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
#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 falcor+unsubscribe@netflix.com.
To post to this group, send email to falcor@netflix.com.
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
.

@trxcllnt
Copy link
Contributor

@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);
  });

@noonian
Copy link
Author

noonian commented Sep 10, 2015

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

@falcor-build
Copy link
Contributor

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 notifications@github.com wrote:

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


Reply to this email directly or view it on GitHub
#132 (comment)
.

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 falcor+unsubscribe@netflix.com.
To post to this group, send email to falcor@netflix.com.
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
.

@greim
Copy link

greim commented Feb 24, 2016

I ran into this need also: #175 I closed the issue, but referencing it here for posterity.

@greim
Copy link

greim commented Feb 24, 2016

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.

@trxcllnt
Copy link
Contributor

@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.

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

No branches or pull requests

4 participants