Giter Site home page Giter Site logo

Comments (10)

jfromell avatar jfromell commented on May 7, 2024 8

Would also like to know how to specify parentName when connection is nested (viewer { cart { items } })

from relay.

wincent avatar wincent commented on May 7, 2024 1

I'm going to close this now because the mutations API is going to be drastically improved, simpler and different in Relay 2, so we aren't likely to be able to dedicate any resources to documenting the old system at this time. (Even so, if somebody wants to submit a PR improving the docs I'll be happy to review it.)

Thanks to everybody who contributed to this thread!

(Just in case anybody stumbles on this thread looking for more info on mutations in the future: since this thread was originally started, we've talked a little bit about the concepts behind mutations: for example, see the videos on the videos page).

from relay.

steveluscher avatar steveluscher commented on May 7, 2024

The outputFields and the fat query are closely related. It's not that the mutation always returns all of the ships for a given faction after having run, its that the mutation makes the faction field available for querying as part of the IntroduceShipMutationPayload. If the client asks, the server mutation shall oblige.

Returning all of the ships as a response to adding a ship is not the goal of exposing faction though. You could think of other things the client mutation might be interested in on faction other than the edges of the ships connection, such as the total number of ships:

class IntroduceShipMutation extends Relay.Mutation {
  /* ... */
  getFatQuery() {
    return Relay.QL`
      fragment on IntroduceShipMutationPayload {
        faction { ships { count } },
        shipEdge,
      }
    `;
  }
  /* ... */
}

So, having added a ship, the response might look like this:

{
  "data": {
    "introduceShip": {
      "clientMutationId": "...",
      "faction": {
        "id": "...",
        "ships": {
          "count": 10
        }
      },
      "shipEdge": {
        "cursor": "...",
        "node": {
          "name": "Millennium Falcon",
          "id": "..."
        }
    }
  }
}

from relay.

steveluscher avatar steveluscher commented on May 7, 2024

Also, the config governs how Relay handles the optimistic response too, so whether or not you fetch the edges on the ships connection from the server, it will know where to stick the new ship before the server has even responded,

from relay.

steveluscher avatar steveluscher commented on May 7, 2024

…and lastly, even if your fat query includes the ships connection with no subfields (ie. faction { ships }), Relay will strip out the edges subfield from the intersection of the fat query and the tracked query, so no refetching of all of the ships takes place. Take a look at https://github.com/facebook/relay/blob/master/src/mutation/RelayMutationQuery.js#L213-L221

I'll make it my job to make this more clear in the mutations docs. Thanks!

from relay.

jardakotesovec avatar jardakotesovec commented on May 7, 2024

Right, thanks. I understand that this covers many use cases in optimal way and definitely makes sense.

How about if the mutation have some more complicated logic and would for example insert ship somewhere in the middle. I wonder what options I have when I want make Relay to refetch ships. Is updating facet using FIELDS_CHANGE way to go?

  getConfigs() {
    return [{
      type: 'FIELDS_CHANGE',
      fieldIDs: {faction: this.props.faction.id},
    }];
  }

from relay.

steveluscher avatar steveluscher commented on May 7, 2024

Exactly!

Leaving this issue open to track improvements to the mutations guide that cover these topics.

from relay.

yuzhi avatar yuzhi commented on May 7, 2024

I am not sure if this is in the docs but any connection not listed in the RANGE_ADD's rangeBehaviors will be refetched from the server and we won't be able to do an optimistic append or prepend for those at the moment. So if you are adding a ship and you also have fetched for orderby:size, that connection would be refetched from the server automatically with the RANGE_ADD config.

from relay.

miracle2k avatar miracle2k commented on May 7, 2024

I also would like better documentation for this. It definitely seems confusing at first, especially that coming into it, I think people are confused why mutations have to be so verbose, expecting Relay to be somehow "smarter".

In particular, the RANGE_ADD configuration. Here's the best that I can figure it:

return [{
  type: 'RANGE_ADD',
  rangeBehaviors: {
    '': 'append'
  },
  // Relay should add which "edge" to a connection?
  edgeName: 'newItemEdge',
  // Which connection? "items" on that dataId
  parentID: this.props.menu.id,
  connectionName: 'items',
  // But why do we need to tell it this?
  parentName: 'menu',
}];

So Relay takes edgeName from the response, takes the object with parentID from it's cache. It then adds the new edge to the connection field "connectionName" of the "parentID" object.

That leaves me with some questions:

  • Why is it necessary that the connection from "connectionName" is part of the response? Shouldn't Relay, with only "parentID.connectionName", already know where to attach the edge?
    I would assume that now, in 99% of the cases, when "parentID" only has one connection of the given type, so it should't even be necessary to tell Relay about "connectionName" in those cases?
  • Why is "parentName" used for? What if my connection is nested more than one level deep? (viewer { items { tags }) - Is the parent the viewer or the items?

from relay.

yungsters avatar yungsters commented on May 7, 2024

I would assume that now, in 99% of the cases, when "parentID" only has one connection of the given type, so it should't even be necessary to tell Relay about "connectionName" in those cases?

Are you suggesting that we scan all fields on the parentID to find the field which is a connection and happens to contain an edges type that matches the type of the returned connection edge? You are certainly right that this could be made easier for a large portion of use cases.

Why is "parentName" used for?

The parentName is the field on the response payload that corresponds to the parent field. This is important in the case that fields on the parent need to be updated.

I agree that it's confusing which of these configurations apply to which things — the response payload? the client data? the schema?

The RelayMutation docblock might help make these clearer:

* - RANGE_ADD provides configuration for adding a new edge to a range.
* {
* type: RelayMutationType.RANGE_ADD;
* parentName: string;
* parentID: string;
* connectionName: string;
* edgeName: string;
* rangeBehaviors:
* {[call: string]: GraphQLMutatorConstants.RANGE_OPERATIONS};
* }
* where `parentName` is the field in the fatQuery that contains the range,
* `parentID` is the DataID of `parentName` in the store, `connectionName`
* is the name of the range, `edgeName` is the name of the key in server
* response that contains the newly created edge, `rangeBehaviors` maps
* stringified representation of calls on the connection to
* GraphQLMutatorConstants.RANGE_OPERATIONS.

from relay.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.