https://kadira.io/blog/graphql/initial-impression-on-relay-and-graphql

http://graphql.org/blog/subscriptions-in-graphql-and-relay/

Facebook recently made GraphQL and Relay open source, so now we can try them out. These are the two main components in Facebook's app architecture that focus on data management. They are in the very early stages.

Since we fixed some of Meteor's data-related issues, I'm really excited about these two projects. I played a bit with both of them and this is my experience and how I feel about them.

I am a die-hard Meteor fan. So, I might talk in favor of Meteor. But I'll try to be open minded and avoid mentioning Meteor.

What's GraphQL

Basically GraphQL is an application layer query language, which queries and mutates (or updates) data. You might think it's somehow related to a graph database. Yes, it has a good relationship with graphs, but it's not tied to a database.

Before looking at GraphQL, let's see what problems it's trying to solve:

  1. Client-side developers should have a way to ask for the data they need.
  2. Server-side developers should have a way to expose the data they have.
  3. There should be an easy and efficient way to query data (the REST API consumes a lot of resources, especially with mobile apps).

To clarify this, let's use Facebook as an example.

Whatever happens in the client apps or in the backend, there are millions of users who want to use Facebook every day. Mostly importantly, there are tons of ways to access Facebook. It has an app for every major platform and those apps have multiple versions. Technically, there might be 100's of apps.

So, adding a new feature should not break any of these apps.

That's where GraphQL is gonna help Facebook (and the rest of the developer community):

With GraphQL, a client-side developer can write a query against a GraphQL server and fetch data. Let's say that in a different version of the app, that developer wants more information. With GraphQL, they simply change the GraphQL query and get the data they need. They never need to ask the server-side developer to create a custom data endpoint.

You can also get most of the data for a given view using a single request to the server.

We'll talk more about GraphQL in a moment.

What's Relay?

Relay is a JavaScript application framework that can talk to a GraphQL server. With Relay, client-side developers can define data needs for each of their components with GraphQL.

Then when rendering a page, Relay aggregates all those GraphQL queries and invokes them against the GraphQL server very efficiently.

It can also mutate data and it supports cool features like optimistic updates. We'll also talk more Relay in a moment.

How GraphQL Works

GraphQL sits between the client apps and the actual data sources. It's a kind of agreement between the client and the server with an efficient querying system.

It's independent of platforms and data sources. You can create a GraphQL server in Node, PHP or any other platform you like. Mobile apps, web apps and anyone else should be able to connect to a GraphQL server. Then they can query and mutate data.

But GraphQL does not comes with a transport layer. That’s the responsibility of a high-level framework, like Relay.

GraphQL also has a very good type system. It's basically built on top of graphs with the types you define. You might feel that you don't need to expose your dataset as a graph. But, if you think closely, 90% of the time your data schema can be structured as a set of graphs.

Let's see some GraphQL

Enough talk. Let's see an example:

Just for a moment, assume that I am the developer who built Product Hunt.

Here, I'm trying to get the data for a typical Product Hunt page (like this). This is how I'm going to get them with GraphQL:

{
product(id: "react-native-for-android") {
name,
link,
votes,
comments {
text
}
}
}

So, it gives something like this as the result:

{
"data": {
"product": {
{
"name": "React Native for Android",
"link": "https://facebook.github.io/react-native/",
"votes": "167"
"comments": [
{
"Huuuuge for cross-platform progress.",
},
{
"Exciting stuff.",
}
]
}
}
}
}

Let's say, I am working on an upgraded version of Product Hunt and I need to display the author right next to the comment. To get that data, I simply change my GraphQL query like this:

{
product(id: "react-native-for-android") {
name,
link,
votes,
comments {
text,
author {
avatar
}
}
}
}

So, it's very easy to add features to the app without touching the server code or any other part of my app.

This is just the surface of GraphQL. Check out the GraphQL docs for more information.

What Does GraphQL Lack?

Everything in GraphQL looks good so far. But it's not the perfect solution.

One thing it's missing is the ability to update clients reactively. In the GraphQL spec, there is no way to subscribe and get updates. There have been some experiments and discussion on how to do so, but we don't have any examples yet.

Right now, to achieve real-time updates, we need to poll the server and get the changes.

What's the Catch?

These days, we talk about isomorphic concepts and sharing code between the client and server.

At the same time, now we are talking about decoupling the client and the server. So, I was confused a bit.

But, Facebook is right.

There should be a clear boundary between the client and the server with a common agreement. So, both parties can build and scale independently.

Isomorphic is not about sharing code between the server and the client. It's beyond that.

For an example, you might want to share some of the stuff you wrote for the web and use it in iOS. Maybe you can share some of the code in every part of your system, including in the server. It doesn't need to be code every time. May be it's some data definition or a set of images.

Finally, I think isomorphic means sharing resources between platforms.

If you need to grab a snack, this is the time. We are gonna discuss more stuff.

How Does Relay Work?

As I mentioned earlier, Relay is an application framework that connects to a GraphQL server and queries and mutates data. It's built on top of React components and it has an express-compatible network layer. But, it's possible to add custom network layers.

With Relay, you can express your data requirement for each UI component using GraphQL. Then, Relay will fetch them for you efficiently. It'll do the complex data management tasks such as:

  • Mutations and handling changes (apply changes after a mutation)
  • Optimistic updates (simulate mutation in the client, so the user doesn't need to wait for the server result to see the change they made)
  • Data caching to reduce server round trips (simply reuse existing data)

If you are coming from Meteor, you’ll feel like these things are available by default in your app.

Oops! Did I just mention Meteor? Sorry!

The Good Parts of Relay

I really like the concept of defining the data requirement in the component itself. Relay can build GraphQL queries and decide what to fetch and when. That's brilliant.

Let's look at an example:

(It's a simple blog.)

This is our BlogPost React component:

class BlogPost extends React.Component {
render() {
return (
<div className="post">
<h1>{this.props.post.title}</h1>
<p>{this.props.post.content}</p>
</div>
);
}
};

Next, we define the data requirements using GraphQL:

BlogPost = Relay.createContainer(BlogPost, {
fragments: {
// this is some GraphQL code.
// `fragment` keyword is used to create a subset of a type.
// (which is Post in this case)
post: () => Relay.QL`
fragment on Post {
title,
content
}
`,
},
});

Then, while loading the page, Relay will fetch these data for you:

Here's the interesting part. Let's say you want show the author right next to the title in the BlogPost component. Simply change the GraphQL query. It's that easy.

There is no need to change anything anywhere in your code.

What's Not Ideal in Relay?

I like the core concept behind Relay. But I don't like how it does mutations and handles changes.

Let's look at the problem first.

If Relay is all about querying data, there is no issue at all. Things start to blur when you call mutations. With a mutation, you update some part of your graph. Relay needs to get the changes done by the mutation and apply them into the app.

For instance, let's say in the above blog example, we called a mutation that adds a new comment. We keep both the comment count and the comments separately. So, for that mutation, we need to update two places in our graph.

The client needs to get these updates after the mutation and apply them correctly. This is a big issue.

How Relay Handles Mutation Changes

In Relay, we do this with fat queries. So, for every mutation, we need to define all the changes it makes as a special GraphQL query like this:

(We need to do this in the client.)

  getFatQuery() {
return Relay.QL`
// Here when we add a new comment we need
// to get the new comment and the count again
fragment on Post {
comments,
commentCount
}
`;
}

I think this is a wrong decision.

Now the client-side developer needs to know the logic behind the mutation and use it inside the client code. It would have been better if Relay could figure it out automatically and apply the changes.

To do this, GraphQL could expose some information to Relay via its introspection functionality.

This would simplify the client-side developer's job.

How Relay Handles Optimistic Updates

With optimistic updates, we try to simulate the server-side mutation inside the client. Thus, we can reflect the UI changes without waiting for the server-side response. This concept is also known as latency compensation.

If we need to get optimistic updates in Relay, we need to run a simulation of that mutation inside the client. To do this in Relay, the client-side developer needs to write the logic.

But actually, this is the job of the server-side developer. It'd be great if the server-side developer could include these simulations while defining the mutation on the server using some sort of GraphQL.

This would simplify the client-side developer's job. They would simply have to call the mutation and Relay would know how to simulate and update the UI.


Suggestions

Finally, I think Facebook did an amazing job with GraphQL and Relay. However, Relay needs some improvements. Here are my suggestions:

  1. Allow the definition of mutation updates and simulations (mutation metadata) in the server. Make it a part of GraphQL.
  2. In the client, get the mutation metadata using GraphQL's introspection functionality.
  3. Then, Relay can apply the simulation and the data changes.

I'm really interested in these suggestions and I’m looking forward to experimenting on them. Let's see what we can do.

[转] Initial Impressions on GraphQL & Relay的更多相关文章

  1. [GraphQL] Create a GraphQL Schema

    we’ll take a look at the GraphQL Language and write out our first GraphQL Schema. We’ll use the grap ...

  2. Spring Boot GraphQL 实战 03_分页、全局异常处理和异步加载

    hello,大家好,我是小黑,又和大家见面啦~ 今天我们来继续学习 Spring Boot GraphQL 实战,我们使用的框架是 https://github.com/graphql-java-ki ...

  3. IOS 开发教程

    http://www.raywenderlich.com/category/ios http://www.raywenderlich.com/50310/storyboards-tutorial-in ...

  4. JavaScript 2016年的概况

    国外的网站stateofjs.com根据超过九千位开发人员的问卷调查,发布了2016年JavaScript的年度概况报名. 注:本文翻译的部分可能存在不准确的情况,请以原文为准. 调查结果的报告目录结 ...

  5. 2016年JavaScript技术栈展望

    如果你正在筹划新的前端项目或者重构现有项目,那么你需要认识到现在的前端开发环境已经今非昔比,这其中有太多的选择了:React.Flux.Angular.Aurelia.Mocha.Jasmine.Ba ...

  6. ReactEurope Conf 参会感想

    React 带来的革命性创新是前端世界过去几年最激动人心的变化.自从接触 React 以来,我深信 React 会改变客户端开发者(包括前端.iOS 和 Android)的开发体验.这次在巴黎举办的  ...

  7. Intel QuickAssist Technology and OpenSSL – Benchmarks and Setup Tips

    Intel QuickAssist Technology and OpenSSL – Benchmarks and Setup Tips 来源:https://www.servethehome.com ...

  8. 1.1 React 介绍

    1.1.1 React 是什么 React IS A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES 来自:React 官方网站 狭义来讲 React ...

  9. 一个iOS开发者对tvOS SDK的初探

    http://www.cocoachina.com/ios/20151001/13652.html 作者:Chris Wagner原文地址:tvOS SDK: An iOS Developer’s I ...

随机推荐

  1. 写个自动安装JDK的shell脚本

    #!/bin/bash ################################################# # # INSTALL JDK AUTOMATICALLY # # auth ...

  2. 如何通过数据库修改WordPress后台登录密码

    大家是否有过因为忘记WordPress后台登陆密码的时候?其实WordPress后台登陆密码的找回或修改的方法有多种,比如通过邮箱重启密码,又或者通过主机控制面板进入数据库修改等等.本篇教程以GoDd ...

  3. 百部BBC经典纪录片,附地址,需要的请抱走

  4. [jobdu]调整数组顺序使奇数位于偶数前面

    这道题的代码没啥好说的,用了O(n)的空间就是水题了.但可以讲一下思考过程.一开始是想O(1)的空间的,然后想从左往右双指针扫,然后根据出现顺序交换遇到的偶数和奇数.但遇到一个问题:1, 2, 3, ...

  5. cheerio返回数据格式

    通读cheerio API { options: { decodeEntities: false, withDomLvl1: true, normalizeWhitespace: false, xml ...

  6. Connection 和Dispose的学习日志

  7. java基础(十)面向对象(五)

    这里有我之前上课总结的一些知识点以及代码大部分是老师讲的笔记 个人认为是非常好的,,也是比较经典的内容,真诚的希望这些对于那些想学习的人有所帮助! 由于代码是分模块的上传非常的不便.也比较多,讲的也是 ...

  8. scanf从文件中读入,printf写入到文件

    重定向方式读写文件 #include <stdio.h> #define LOCAL int main() { #ifdef LOCAL freopen("input.txt&q ...

  9. XML文档部署到Tomcat服务器上总是加载出错

    config.xnl 起初文档路径是在src/Dao/config.xml 在Dao目录下BaseDao类中,解析config.xml文件路径 path="/Dao/config.xml&q ...

  10. HashMap和Hashtable

    HashTable 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的  速 ...