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. 2016最新Java笔试题集锦

    更新时间:2015-08-13         来源:网络         投诉删除 [看准网(Kanzhun.com)]笔试题目频道小编搜集的范文“2016最新Java笔试题集锦”,供大家阅读参考, ...

  2. WKWebView-b

    上一篇文章我们使用了JavaScriptCore框架重写了之前的示例,iOS8苹果偏爱HTML5,重构了UIWebVIew,给我们带来了WKWebView,使其性能.稳定性.功能大幅度提升,也更好的支 ...

  3. Python抓取双色球数据

    数据来源网站http://baidu.lecai.com/lottery/draw/list/50?d=2013-01-01 HTML解析器http://pythonhosted.org/pyquer ...

  4. Android UI基础教程 目录

    从csdn下载了这本英文版的书之后,又去京东搞了一个中文目录下来.对照着看. 话说,这本书绝对超值.有money的童鞋看完英文版记得去买中文版的~~ Android UI基础教程完整英文版 pdf+源 ...

  5. Jinja2学习笔记暨官方文档的翻译

    http://blog.csdn.net/lgg201/article/details/4647471 呵呵, 刚刚看完Python模板引擎Jinja2的文档, 感觉很好, 觉得动态语言真是很好.  ...

  6. 有感,懂市场比懂产品重要,懂产品比懂技术重要——想起凡客诚品和YY语音了

    一个创业公司,最好三样都要有,但应该CEO是懂市场,经理懂产品,程序员最好懂技术厉害一点-这还不算,销售也要厉害一点,不能守株待兔- 美工——有钱最好请个美工,最起码也要请人设计修改一下- 财务——不 ...

  7. xmlns:android作用以及自定义布局属性

    要定制Android layout 中的 attributes关键是要明白android中命名空间定义如: xmlns:android="http://schemas.android.com ...

  8. lc面试准备:Repeated DNA Sequences

    1 题目 All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: &quo ...

  9. bzoj1257

    这道题初看确实没什么思路,感觉之前的数论知识都用不上,只好自己找规律首先当n>=k 这部分是很容易直接算出的下面我们先来尝试这穷举i,不难发现当穷举i时,总存在一段连续的除数,k div i=p ...

  10. bzoj2064

    这道题初看真的毫无思路,又是合并又是分裂的 但实际上我们知道,当两组和相等的时候才能由一组变成另一组 我们将初始状态和最终状态划分成若干对,每对中的两组元素和相等的 不难发现,最少步骤=n+m-2*对 ...