Relay: [meta] New Relay APIs (previously codenamed "Relay 2")

Created on 3 Sep 2016  路  77Comments  路  Source: facebook/relay

New Relay APIs

The core team is currently focused on developing the next major version of Relay, which we have been referring to as "Relay 2" as a working title, but which will ultimately be just a new set of APIs within the existing Relay. The new APIs are the best parts of Relay today - co-located GraphQL and React components and a declarative API - but is simpler, faster, and more predictable. This issue is to track our overall progress and give us a place to point people toward information.

More Information

  • Check out our recent blog post on the state of the project and our goals/plan going forward.
  • @wincent's deep dive explains how Relay 2 works from a technical perspective; check this out if you're curious about the implementation and how it differs from current Relay.
  • @josephsavona's React Rally talk provides an overview of the new APIs from a product developer's perspective, including the types of performance enhancements and API simplifications it unlocks.

FAQs

Do I have to relearn everything?

The core concepts of Relay continue to apply: co-located GraphQL and render logic, a declarative API that lets you specify what data you need, not how to fetch it. If you're familiar with Relay today, the updated Relay should feel familiar, with some rough edges removed (no more Routes, for example, just queries and variables). If you're _new_ to Relay, there will less concepts to learn and, we hope, it should be easier to get started.

There are definite API differences, but the core concepts are the same and the API changes serve to make Relay simpler and more predictable.

What is the upgrade path?

Note that _we will continue to support the current API for the foreseeable future_ - we're using it too! Where possible, we will provide tools to help the community upgrade their own apps. We're currently exploring a limited interoperability API as well as codemods and other tools.

How can I prepare for the new API?

In general, the main theme is to reduce dynamic APIs that can prevent Relay from understanding the structure of a query statically (i.e. at build time). Examples of such dynamic APIs in current Relay are:

  • RelayMutation and fat/tracked queries. Future releases will deprecate this API in favor of a static mutation API. We recommend using RelayGraphQLMutation to ease the transition to new mutations.
  • RelayContainer#prepareVariables(). Future releases will deprecate support for this function; the workaround is to use (global) query variables and prepare dynamic values at the Renderer.
  • RelayContainer#initialVariables() with runtime function calls specifically (inline constants/literals such as initialVariables: {count: 10} are static, runtime function calls such as initialVariables: {count: getRuntimeValue()} are not). Future releases will deprecate support for dynamically assigned initial variables. Similar to prepareVariables, a workaround will be to use (global) query variables.

When will the updates to Relay be released?

We open source tools that we have proven in production. We're working to refine the product developer experience, finish/polish some features, and ship the first apps using it.

Where can I learn more / follow progress?

The best way to follow our progress is to read our meeting notes. We publish these semi-weekly, and are exploring a new format with more detailed status updates about sub-projects. We cannot guarantee that we can always keep this issue up to date, so always see the meeting notes for updates.

High-Level Tasks

Below is a high-level overview of the work remaining to release the new APIs and core:

  • [x] Introduce a static mutation API: Relay.GraphQLMutation
  • [x] Poly-fill the new core's public API via the legacy core.
  • [x] Introduce static query APIs (new Renderer and Container variants)
  • [x] Deprecate old query APIs (Relay.RootContainer, Relay.Renderer, Relay.Container)
  • [x] Introduce the new core.
new-core-api

Most helpful comment

I don't know about you guys but I wrote a letter to Santa.

All 77 comments

Hi,

Regarding When will Relay2 be released? I appreciate and admire Facebook's model. I am needing to make a decision on Relay 1 vs 2 within the month.

If FB is targeting say H1 2017, then I will go with Relay 1. Otherwise, if the target is say EOY, I will stick with a promise-based fetch to GraphQL and wait for Relay 2. I am trying to reduce cognitive overload for the teams.

So, without being overly arrogant, is it possible to narrow your target down a bit?

Thanks either way.

Regards,
Irvin

@iwaldman I believe a lot of people are facing this decision so a better roadmap will be much appreciated. +1

Regarding release date, we're working to make this happen but aren't ready to make a call on the date yet (as you know scheduling is hard). We'd rather not disappoint by giving an optimistic estimate and then failing to hit it. The tricky part is telling whether your estimate is optimistic...

For now your best bet is to keep your eye on our weekly meeting notes (in the meta directory of their repo) to get a sense of what we're working on at the moment.

Greg, Thanks for responding.

I'm curious if you guys can say if the cache manager API will be changed significantly in Relay 2? There is some work I'd like to do on relay-cache-manager but I'm curious if it might be better to hold off and see the new API, if there is one?

@Aweary We gave a preview of a possible disk-caching API for Relay 2 in our React Rally talk. We don't have a definite timeframe for Relay 2, so I would encourage making improvements in your npm module for now.

Eager to use!
Seems there are some slight change in Relay Specification.(So seems will need restruct some data model for old code?)
Hope the beta version will be released soon. So we can use the beta version in our development.

@iamchenxin You shouldn't need to restructure your data model; the whole point of GraphQL is to _abstract away_ implementation details of data storage and express it in a natural, expressive, product-centric way.

@wincent Im referring to Client side.(Data fetched by Relay.QL, forgive my poor english). I saw the video, but not sure if it will need some restruction for the old React Data Flow to take advantage of Relay 2. (ex: the new RelayConnection seems need to separate some data logic between parent and its children )
Hope the beta version will come soon.
Thanks for your hard working.

Just out of curiosity, l never tried relay 1, so l am not sure if this is possible in that version to.

But server-side rendering, is this going to be supported?

Also server-side rendering of some fields, then client side fetching to render others? - okay i think this is just solved through deferred queries

Looking forward to it @josephsavona @wincent et al. Let me know if there's something we can help with.

Is there any update on when Relay 2 will be released?

@nikhilag: I'm drafting a status update. Will share soon.

@wincent: Thanks for your quick response! Looking forward to the update. I am sure lots of people are excited and eager to use the next version of Relay!

Previously there was discussion about releasing a Relay 'core' library. Is something like this part of the plan for the release of Relay 2?

Two libraries similar to redux/react-redux would be nice.

I just hope that we will get to see a prerelease so the community can also suggest breaking changes.

@sgwilym: status update is drafted. Gathering feedback on it before publishing. I feel pretty confident that we'll be able to share the update some time between Date.now() and Date.now() + Infinity. Thanks for your patience in the meantime.

I am stealing this ".... some time between Date.now() and Date.now() + Infinity."

The good thing about Date.now() is that it changes every time you check

@wincent Sorry to bother you again but just wanted to check if you have a rough timeline on when relay 2 might be ready. It's just that Relay 2 solves a bunch of problems including client side state management and so I really hope to start using it soon instead of a mix of Redux and Relay.

Just checked the meeting notes and it looks like there hasn't been one in more than a month, are those meetings still happening?

I don't know about you guys but I wrote a letter to Santa.

@wincent Is there any update on Relay 2?

@josephsavona or @wincent, I was wondering what happened to the meetings notes. They used to be published every week or so, now it's been 2 months. Does the relay team still meet and develop? Is Relay still alive and well? Is Relay 2 still a thing? I understand the difficultly with timelines, but just a simple pulse to help us know that this is still an active project would be great. Is facebook moving on to something else? Thanks for all the hard work and pioneering!

Thanks for the messages. We've been in crunch mode preparing Relay "2" (the new core and product APIs), and integrating it into the first products. Were hoping to share more soon, but tl;dr yeah we're still working on this :-)

@josephsavona Its so happy to hear from you. I firmly believe Relay2 is the right way, and worth to wait. I temporarily block some part of my project for waiting Relay2.

_I don't know where your code is, but I will find it, and I will release it._

@josephsavona based on 2016-12-09-update.md, seems the only things will be changed are some kind of APIs? Will the graphql relay specification be the same between v1 and v2?

@iamchenxin : The GraphQL specification doesn't change. We'll have this new API that enables the faster and simpler core if used throughout an app.

I was writing a new issue but I figured it might be too trivial:

From updated docs ( #1480 ):

Restricting yourself to the low-level API is a useful preparatory step that will help you ready your codebase for migration to the new static Relay core.

I was about to start rewriting my mutations but because my project won't be pushed to production for at least next few months (hopefully I get my hands on new shiny "Relay 2" by then), it would be awkward to do it several times when I have other stuff to do. Therefore I have the following two questions:

  • Is "Relay 2" mutation public API "ready" in terms of overall idea, properties, methods and naming?
  • Is it going to be the same as Relay.GraphQLMutation? Would it be my only huge mutation rewrite?

@unirey Good question, I added a section to the summary with notes about the transition. For mutations specifically, the transition from Relay.Mutation to RelayGraphQLMutation involves changing from a dynamically constructed query to writing a static mutation query, which can require knowledge about each product and is less amenable to automated codemods. It's possible that the mutation API may still change after that, but we expect those changes to be more minor by comparison (and possibly more amenable to codemods). If you're writing new mutations, we'd recommend using RelayGraphQLMutation.

@josephsavona Thank you.

I hope to get my hands on persisted queries in near future (it's not in "Relay 2" as far as I know), static queries should be the key part to add this feature to Relay core.
This would fix the biggest and most complicated problem with GraphQL (for me at least): it's hard to distinguish normal (but deep and complex) queries from just malicious queries from _e.g_ attackers.

Every solution today (depth limit, adding cost to operations, query whitelist _etc_) is kind of tricky to pull off.

@unirey The new core supports persisted queries, though there will probably be some configuration involved and we'll have to figure out how to make this work in OSS.

Where can I find more examples of the RelayGraphQLMutation api?

This is a use-case test of a library I'm working on right now. It's not really meant to be a boilerplate or an example specifically for relay, but it does use the new mutation API.

At least at the time I made those examples, the only uses of RelayGraphQLMutation I could find were in the official docs and tests.

@nikolal I am gonna try this https://github.com/facebook/relay/issues/1046#issuecomment-272358621 hope you find it useful.

interested to know how server-side rendering will work in relay 2 (or if it will be supported)?

@robrobkay51 Our overall approach with the new core has been to build simple primitives that can be built upon in user space. So for example, there is a clear separation of the React integration layer and the core - the former being implemented entirely via the public API of the latter. It might take a few releases to refine and document this, but i expect that it will be easy for the community to build upon this to make a server rendering module for Relay.

@josephsavona Looking on the high-level tasks on top and wondering if support for local schema is included there and in which step - "Introduce static query APIs" or "Introduce the new core." ? Thanks for hint. Basically wondering if its behind the corner.. or still far away.. Thanks!

+1 for local schema support, this is a big showstopper in my quest to ditch Redux and go all Relay.

We have a prototype of local schema working in the new core, but that's likely something the team will look at only after the new core is released.

@josephsavona That's awesome. We're excited for the new core. Thanks for all your hard work!

@josephsavona Can you confirm if the new core is likely to support "offline" or if this will be easy to build with a community addition? Is there a plan for the new core's client side schema to provide any form of compatibility with redux-devtools, or would that not make sense? Oh and finally I have to ask, but do you have any more ideas on when it may be released :)

Massive thanks for relay! Its had a massive impact on our team productivity and how we're building the next iteration of Mixcloud!

I'm in the position of needing to make a decision re: Relay for a production application ASAP. Making the decision to use Relay 1 doesn't seem sensible at this stage, especially with Relay 2 on the horizon.

So I hate to be that guy, but is there anymore news regarding release date at this stage?

If there is no estimated release date at this stage, what would you advise for people in a similar position to me? Use Relay 1, wait for Relay 2 or use an alternative such as Apollo?

P.S. Massively appreciate all the hard work that's going into Relay 2 and really excited for the release! :)

I think we're feeling the Osborne effect. It's kinda like what happened with Angular 2. It might be better if we had never known about Relay 2. I agree with @robrobkay51 that it would be nice to know something about what's going on with the API's in terms of timelines. I also think, however, that as software developers we all understand that timelines are tricky, if not impossible, in most cases.

I wouldn't hesitate to adopt Relay in its current form, if you've conducted your analysis and concluded that it is a good fit for your application.

At Facebook we have thousands of Relay components deployed in production, so making an overhaul that used a drastically different API was never going to be viable. Instead, we took special care to keep things as aligned as possible, and we've personally migrated large product surfaces areas to the new API to get a feel for the amount of work required to convert.

As for concrete release dates, obviously we can't comment. But having said that, FB speakers will be speaking at public events in the near future (React.js Conf, F8 etc); if we have news to report or things to share by those dates, we will. In the meantime, keep your eye on the meeting notes directory in this repo's meta directory for a record of what we're talking about (no sync this week because it was a hackathon week).

@robrobkay51 if you are not already a Relay expert go Apollo. I initially chose Relay even though I knew Apollo is newer, more featured and better documented on the hopes of Relay 2. After a week of frustration with ancient dependencies, large boilerplate code and a mountainous learning curve, with hopes fading of Relay 2 landing anytime soon I thought I would give Apollo a shot. In the first afternoon I had progressed more than the entire week previous.

In no time at all I even had a pull request merged. @stubailo, @helfer and the other guys are super engaged and are doing a fantastic job at driving progress.

Take a look at the progress adding a GraphQL example to Next.js. The Apollo example is now done and dusted, Relay not so much.

@wincent So hypothetically, if someone adopted Relay 1 now and then wanted to migrate to Relay 2 at a later date, I think it would be really useful to know really roughly how much work might be involved based on the migrations that you've been involved with to date at FB ('and we've personally migrated large product surfaces areas to the new API to get a feel for the amount of work required to convert.') Ofc, looking for an estimate here rather than an exact figure.

@robrobkay51 We're adopting Relay 1 with the new GraphQLMutation interface. The learning curve is more severe than anything I've ever worked with. I think a big part of this is b/c Facebook hasn't been incentivized at all to continue investing in documentation and examples for the last year or so, with Relay 2 coming up.

From our experience I'd still advise Relay 1 if you're building a big, long-term project; FB has promised a smooth migration path to Relay 2. However if you only plan to spend 1-2 months coding your project or it won't be in use in 3 years, I wouldn't recommend it as you'll spend a lot of time tweaking to try and get things working.

@wincent I agree that it would be nice to have an idea of how much work we may want to plan for to migrate to Relay 2.

Very hard to give a quantitative answer about "how much work" is involved in migrating. In our experience porting products at Facebook, many components can be ported by an automated codemod (and we'll share the jscodeshift scripts that we used for this purpose).

For example:

class LikeButton extends React.Component {
  render() {
    var {page} = this.props;
    return <Button label={'Like ' + page.name} />;
  }
}

module.exports = Relay.createContainer(
  LikeButton,
 {
    fragments: {
      page: () => Relay.QL`
        fragment on Page {
          name
        }
      `,
    },
  }
);

would become something like:

class LikeButton extends React.Component {
  render() {
    var {page} = this.props;
    return <Button label={'Like ' + page.name} />;
  }
}

module.exports = createFragmentContainer(
  LikeButton,
  graphql`
    fragment LikeButton_page on Page {
      name
    }
  `
);

(Usual disclaimers apply: API subject to change and all that; hold off on questions about the specific details here as we'll be documenting it all with the release.)

I include this merely as an illustrative example of the simple case. More complex cases involving variables will require a little more work, but only incrementally so. Our goal is that the performance benefits of moving to the new APIs and core should make this migration cost worthwhile. Sorry that I can't be more specific, but it's hard to give a precise sense for the cost of a migration other than to broadly call it "reasonable".

@wincent That's helpful - at least in this example, there's a relatively straightforward mapping between the old and new way.

Looks like a great syntax improvement! I really like that there is now a fragment name, identifying parts of queries via the fragment name has been really useful for us.

@stubailo it looks like this should make a migration to Apollo easier as well, since it's using graphql template tags?

@idris: the tags contain literal/static GraphQL text (no more interpolation), so it should make for better interoperability with any tooling that "speaks" GraphQL (syntax highlighting, GraphiQL, alternative libraries etc).

Yeah that's great. I can imagine creating our own createFragmentContainer that lets us change libraries like Apollo and Relay with a few lines of centralized code.

Obviously there are a few GraphQL differences that wouldn't be as easy (Relay enforces relay's pagination, different GraphQL features implemented between libraries, etc). But this is a huge step!

Can this recommendation be removed made more doable:

RelayMutation and fat/tracked queries. Future releases will deprecate this API in favor of a static mutation API. We recommend using RelayGraphQLMutation to ease the transition to new mutations.

I had to override the default environment using a hack to set credentials to same-origin.

I'm using this.props.relay.forceFetch() to essentially inefficiently refresh the page after a successful commit...

I've lost the my sense of developer productivity trying to consume the low level API, even though I really appreciate your good hard work!

@mattferrin, two points since we've just been figuring this out ourselves:

  1. We use a custom network layer at the root app level (Relay.injectNetworkLayer(NetworkLayer);). When crafting a GraphQLMutation, it seems to work fine to supply Relay.Store as the environment argument, so it isn't necessary to initialize a new environment.
  2. Are you using mutator configs to process the mutation response payload into the Relay cache?

@cberkom Regarding point 1, in order to customize the endpoint and use the same origin for the credentials, so that the request is authorized, you must set the network layer manually.

Relay.Store._storeData._mutationQueue._storeData._networkLayer = new DefaultNetworkLayer(customEndpoint, {
   credentials: 'same-origin'
})

On point 2, yes.

mutation.commit([{
  type: 'FIELDS_CHANGE',
  fieldIDs: {
    subViewer: 'singleton_sub_viewer_id',
  }
}])

Using this query:

let query = Relay.QL`mutation GraphM {
  insertEmployeeEvent(input: $input) {
    clientMutationId
    subViewer {
      timekeepingEmployeesEvents {
        employeeName
        eventTime
        eventType
      }
    }
  }
}`

(If it's relevant, I tried to work off master but couldn't get it to run, so I'm consuming "react-relay": "^0.10.0". )

@mattferrin On point 2, are you using this.props.relay.forceFetch() because you need to fetch more data than the mutation returns, or because the response data from the mutation isn't updating the Relay cache as intended?

@cberkom Honestly, the store updates fine, but doing a this.forceUpdate() on a parent component didn't re-render the changes to the records. I had to use forceFetch, but the Relay.Store after doing a forceFetch looks identical to me.

Relay.Store upon initial render:

{
   "_storeData":{
      "cachedRecords":{

      },
      "cachedRootCallMap":{

      },
      "queuedRecords":{

      },
      "records":{
         "client:-20020347631":{
            "__dataID__":"client:-20020347631",
            "__typename":"Viewer",
            "isAuthenticated":true,
            "isInRoleDesktopClient":true,
            "isInRoleInternal":true,
            "isInRoleOwner":true,
            "nEmployee":{
               "__dataID__":"client:-20020347632"
            },
            "subViewer":{
               "__dataID__":"singleton_sub_viewer_id"
            }
         },
         "client:-20020347632":{
            "__dataID__":"client:-20020347632",
            "__typename":"NEmployee",
            "employeeId":29641,
            "name":"Ferrin, Matt"
         },
         "singleton_sub_viewer_id":{
            "__dataID__":"singleton_sub_viewer_id",
            "__typename":"SubViewer",
            "timekeepingEmployeesEvents{employeeIds:[],fromDate:\"636227533873210000\",toDate:\"636227533873210000\"}":[

            ],
            "id":"singleton_sub_viewer_id",
            "timekeepingEmployeesEvents{employeeIds:[0:29641],fromDate:\"636227533873210000\",toDate:\"636227533873210000\"}":[

            ]
         }
      },
      "rootCallMap":{
         "viewer":{
            "":"client:-20020347631"
         }
      },
      "nodeRangeMap":{

      }
   }
}

Relay.Store in Relay.GraphQLMutation onSuccess callback after commit:

{
   "_storeData":{
      "cachedRecords":{

      },
      "cachedRootCallMap":{

      },
      "queuedRecords":{

      },
      "records":{
         "client:-20020347631":{
            "__dataID__":"client:-20020347631",
            "__typename":"Viewer",
            "isAuthenticated":true,
            "isInRoleDesktopClient":true,
            "isInRoleInternal":true,
            "isInRoleOwner":true,
            "nEmployee":{
               "__dataID__":"client:-20020347632"
            },
            "subViewer":{
               "__dataID__":"singleton_sub_viewer_id"
            }
         },
         "client:-20020347632":{
            "__dataID__":"client:-20020347632",
            "__typename":"NEmployee",
            "employeeId":29641,
            "name":"Ferrin, Matt"
         },
         "singleton_sub_viewer_id":{
            "__dataID__":"singleton_sub_viewer_id",
            "__typename":"SubViewer",
            "timekeepingEmployeesEvents{employeeIds:[],fromDate:\"636227533873210000\",toDate:\"636227533873210000\"}":[

            ],
            "id":"singleton_sub_viewer_id",
            "timekeepingEmployeesEvents{employeeIds:[0:29641],fromDate:\"636227533873210000\",toDate:\"636227533873210000\"}":[
               {
                  "__dataID__":"client:-20020347635"
               },
               {
                  "__dataID__":"client:-20020347636"
               }
            ],
            "timekeepingEmployeesEvents":[
               {
                  "__dataID__":"client:-20020347633"
               },
               {
                  "__dataID__":"client:-20020347634"
               }
            ]
         },
         "client:-20020347633":{
            "__dataID__":"client:-20020347633",
            "__typename":"EmployeeEvent",
            "employeeName":"Ferrin, Matt",
            "eventTime":null,
            "eventType":"FinishShift"
         },
         "client:-20020347634":{
            "__dataID__":"client:-20020347634",
            "__typename":"EmployeeEvent",
            "employeeName":"Ferrin, Matt",
            "eventTime":"2017-02-15T11:04:06.1Z",
            "eventType":"BeginShift"
         },
         "client:-20020347635":{
            "__dataID__":"client:-20020347635",
            "__typename":"EmployeeEvent",
            "employeeId":29641,
            "employeeName":"Ferrin, Matt",
            "employeeTimeAgreement":null,
            "employeeTimeClarification":null,
            "employeeTimeId":"19c610fd-790e-400b-a805-6870493f8ec4",
            "employeeTimeSignature":null,
            "eventName":"Finish Shift",
            "eventDate":"2017-02-15T11:04:06.1Z",
            "eventTime":null,
            "eventType":"FinishShift",
            "fundingSourceId":null,
            "fundingSourceName":null,
            "runId":null,
            "runName":null,
            "serviceId":null,
            "spaceType":null
         },
         "client:-20020347636":{
            "__dataID__":"client:-20020347636",
            "__typename":"EmployeeEvent",
            "employeeId":29641,
            "employeeName":"Ferrin, Matt",
            "employeeTimeAgreement":null,
            "employeeTimeClarification":null,
            "employeeTimeId":"19c610fd-790e-400b-a805-6870493f8ec4",
            "employeeTimeSignature":null,
            "eventName":"Begin Shift",
            "eventDate":"2017-02-15T11:04:06.1Z",
            "eventTime":"2017-02-15T11:04:06.1Z",
            "eventType":"BeginShift",
            "fundingSourceId":null,
            "fundingSourceName":null,
            "runId":0,
            "runName":null,
            "serviceId":null,
            "spaceType":null
         }
      },
      "rootCallMap":{
         "viewer":{
            "":"client:-20020347631"
         }
      },
      "nodeRangeMap":{

      }
   }
}

Relay.Store readyState after forceFetch:

{
   "aborted":false,
   "done":true,
   "error":null,
   "events":[
      {
         "type":"NETWORK_QUERY_START"
      },
      {
         "type":"CACHE_RESTORE_START"
      },
      {
         "type":"CACHE_RESTORED_REQUIRED"
      },
      {
         "type":"NETWORK_QUERY_RECEIVED_ALL"
      }
   ],
   "ready":true,
   "stale":false,
   "mounted":true
}

Relay.Store after forceFetch:

{
   "_storeData":{
      "cachedRecords":{

      },
      "cachedRootCallMap":{

      },
      "queuedRecords":{

      },
      "records":{
         "client:-20020347631":{
            "__dataID__":"client:-20020347631",
            "__typename":"Viewer",
            "isAuthenticated":true,
            "isInRoleDesktopClient":true,
            "isInRoleInternal":true,
            "isInRoleOwner":true,
            "nEmployee":{
               "__dataID__":"client:-20020347632"
            },
            "subViewer":{
               "__dataID__":"singleton_sub_viewer_id"
            }
         },
         "client:-20020347632":{
            "__dataID__":"client:-20020347632",
            "__typename":"NEmployee",
            "employeeId":29641,
            "name":"Ferrin, Matt"
         },
         "singleton_sub_viewer_id":{
            "__dataID__":"singleton_sub_viewer_id",
            "__typename":"SubViewer",
            "timekeepingEmployeesEvents{employeeIds:[],fromDate:\"636227533873210000\",toDate:\"636227533873210000\"}":[

            ],
            "id":"singleton_sub_viewer_id",
            "timekeepingEmployeesEvents{employeeIds:[0:29641],fromDate:\"636227533873210000\",toDate:\"636227533873210000\"}":[
               {
                  "__dataID__":"client:-20020347635"
               },
               {
                  "__dataID__":"client:-20020347636"
               }
            ],
            "timekeepingEmployeesEvents":[
               {
                  "__dataID__":"client:-20020347633"
               },
               {
                  "__dataID__":"client:-20020347634"
               }
            ]
         },
         "client:-20020347633":{
            "__dataID__":"client:-20020347633",
            "__typename":"EmployeeEvent",
            "employeeName":"Ferrin, Matt",
            "eventTime":null,
            "eventType":"FinishShift"
         },
         "client:-20020347634":{
            "__dataID__":"client:-20020347634",
            "__typename":"EmployeeEvent",
            "employeeName":"Ferrin, Matt",
            "eventTime":"2017-02-15T11:04:06.1Z",
            "eventType":"BeginShift"
         },
         "client:-20020347635":{
            "__dataID__":"client:-20020347635",
            "__typename":"EmployeeEvent",
            "employeeId":29641,
            "employeeName":"Ferrin, Matt",
            "employeeTimeAgreement":null,
            "employeeTimeClarification":null,
            "employeeTimeId":"19c610fd-790e-400b-a805-6870493f8ec4",
            "employeeTimeSignature":null,
            "eventName":"Finish Shift",
            "eventDate":"2017-02-15T11:04:06.1Z",
            "eventTime":null,
            "eventType":"FinishShift",
            "fundingSourceId":null,
            "fundingSourceName":null,
            "runId":null,
            "runName":null,
            "serviceId":null,
            "spaceType":null
         },
         "client:-20020347636":{
            "__dataID__":"client:-20020347636",
            "__typename":"EmployeeEvent",
            "employeeId":29641,
            "employeeName":"Ferrin, Matt",
            "employeeTimeAgreement":null,
            "employeeTimeClarification":null,
            "employeeTimeId":"19c610fd-790e-400b-a805-6870493f8ec4",
            "employeeTimeSignature":null,
            "eventName":"Begin Shift",
            "eventDate":"2017-02-15T11:04:06.1Z",
            "eventTime":"2017-02-15T11:04:06.1Z",
            "eventType":"BeginShift",
            "fundingSourceId":null,
            "fundingSourceName":null,
            "runId":0,
            "runName":null,
            "serviceId":null,
            "spaceType":null
         }
      },
      "rootCallMap":{
         "viewer":{
            "":"client:-20020347631"
         }
      },
      "nodeRangeMap":{

      }
   }
}

@mattferrin Can you file a new issue to discuss?

@josephsavona Yes, soon. Thanks.

Edit:
https://github.com/facebook/relay/issues/1546

@josephsavona any news on this.., i am going to start a new project on monday can we expect new core beta meantime ?

@chandu0101 see @wincent's comment on this thread.

@josephsavona thank you :)

One request - Please keep in mind serverless architecture while designing the modern Relay, especially for subscriptions. With AWS Lambda, Google Cloud Functions and Azure Functions gaining popularity, it might be worth considering how GraphQL and Relay will work in the serverless world.
We are already using GraphQL with Lambda but we have not been able to find any solution that can allow subscriptions to work in the serverless architecture.

I am about to launch a project. Would you please provide an extremely rough estimate of when the first release would be? Like within 1H or within this year?

@tanekim77 Even I have been hoping for the last few months that this releases soon but the facebook team can't commit on any particular date. The only planning you could do is to perhaps use Relay 1 so that migrating to Relay 2 will be easier but it's probably not a good idea to plan a project using a tool that hasn't released yet. I learnt this lesson the hard way :)

We have a (pretty broken) alpha on npm now and are working hard to get it fully working in OSS. Stay tuned!

@kassens are talking about 1.0.0-alpha.1': '2017-03-31T02:14:35.075Z version of react-relay on npm ?

Yes, but there's more packages now:

babel-plugin-relay
react-relay
relay-compiler
relay-runtime

There's currently still missing examples of making it actually run and work together, but most of the building blocks are there.

@kassens
Yep, for now, just one example on a github would be appreciated. Thanks!

@unirey These are the exact thoughts I had as well :)
I was wondering if there was any way to use IoT in GraphQL Subscriptions but I guess not. After reading your post, it became clear to me that I should just use IoT directly similar to https://serverless.com/blog/serverless-notifications-on-aws/

One problem with the server approach is that if we have two GraphQL endpoints, it seems extra work for mutations on serverless GraphQL to tell the EC2 server to send the updated information over websocket to the client.

@nikhilag I think graphql serverless subscriptions is not related to Relay structure, please move this issue into graphql repo

this SO question should help: http://stackoverflow.com/questions/33926619/is-it-possible-to-use-socket-io-with-aws-lambda/33927897#33927897

@tanekim77 That's what we're working on, but we still have a few things to work out where we need to remove the internal dependencies.

Great news, thanks for all the hard work Relay team.

Relay Modern is officially out so we can close this. Let's do any required follow-up in other issues.

Was this page helpful?
0 / 5 - 0 ratings