构建更好的GraphQL API:用图思考

原文链接:https://graphqlme.com/2017/11/11/build-better-graphql-apis-thinking-in-graphs/


构建更好的GraphQL API:用图思考_第1张图片

        当我们正处在学习一门新技术的过渡期时,人们便会遇到两个可能导致他们放弃学习的巨大的阻碍:

        1. 在学习者能够亲眼看到并体会到好处前,有太多他们需要了解的东西;

        2. 转换之前的规范(范式)是很困难的,并且他们突然醒悟的那一刻是需要一些时间的。

        如果你问我,那么第一个能够很好解答这个问题的是GraphQL。GraphQL的优点之一是由于比较类似GraphiQL,使用它能够很早就能上手并看到其带来的好处,而这也给了人们足够的继续学习下去的动力。尽管如此,范式仍然可以说是一些人的障碍。此处有一个十分重要的心态上的转变--即是从REST到GraphQL的心态转变,同时,这也会导致出现一些设计不很精致的试图从REST专属的规范粘贴到GraphQL中的API。

        停止从端进行思考

        如果你还未花费长时间GraphQL,尤其是你没有使用REST很多年的经历,那么你很可能仍然是从端出发思考的,并且没有意识到这一点。这对于设计一个伟大、容易的方法来使用GraphQL API是很不利的。如果你想建立一个直观的API,那么第一步是准确地看到你仍然在从端的角度思考这个方法。

        但是稍等下,如果刚刚我说的是真的,而且你甚至没有意识到你是这么做的,那么你要如何得知要改变什么或者你是否有改变的需要呢?让我们来看一些可以表明你仍然是陷于端点心态(endpoint midset)的标志。

        1. 你发现你自己映射出REST端点,并尝试把他们填入到你的GraphQL API中。

        2. 你尝试建立一种可以允许你按照 resource>action进行钻取或反之亦然的模式。例如:

{

user {

create(...) { … }

}

}

        3.你正在尝试通过观察什么页面可能需要哪一部分的资源这种方法来分离出一些资源。例如,页面A只需要一个用户名和电子邮件,但是页面B除了需要这些还加上他们的电话号码和地址。所以我需要给用户分配两个字段(field),一个用于返回页面A的数据而另一个返回页面B的数据。

        4. 当你设计对象类型时,你会问你自己关于将运用该资源来确定在该类型上要公开什么数据和关系页面的问题,(有些人可能会在这一点上与我争论-我不去说你不应该去考虑客户端的需求,而只是这个问题应该更倾向于“客户是否需求这个”而不是“这个页面需要的是什么”)

        5. 你不断地称呼这些字段(fields)为端或不断地将它们与端进行比较。

        6. 你的字段是用为了取得关系,必须发送一条请求来从字段获得id并在随后的请求中使用它来获得你所感兴趣的相关条目这种方法设计出的。例如,在请求#1中获取comment{userId},然后把它发送到第二个用user{id:userId}以获得user的请求。

        还有更多的标示,但是在我的经验中这很常见。现在,我并不是提及这些来羞辱某人--这是掌握GraphQL最难的一个方面,并且这也需要花些时间来做出从图表思考而不是从端思考的一个转变。如果上述情况和你的类似,而你又正好想知道如何开始以图思考以及这是什么意思,那么请继续!

        如何开始用图思考

        在GraphQL上有很多资料在讨论这个“用图思考”的概念,吹捧其优于用端思考,或者讨论我们如何以这种方式自然而然地思考数据,但我还没有看到很多对它进行解释的。我曾见过很多的开发人员挣扎在对他们的思考方式做出转变,而这同样也花了我一些时间。这是一个核心概念,而你一旦把它攻克下来,你就会豁然开朗,而后设计你的规范将变成一件非常简单的事。

        下面我将解释为了弄清楚在我的模式中如何构筑我的对象的类型我都做了哪些工作。在我做这之前,把我们有的东西全部扔掉--忘记端、有效载荷等,而只关注这一件事。

        我是这么做的:

        但我正查看我构建的GraphQL对象时,我问我自己“客户端从这个对象可能需要获取什么数据或是关系”。

        让我们举一个例子。我有一个可以代表用户的UserType。此时会自然而然想到“这儿应该有什么什么页面,我们要如何...”在此打住,这是从端进行思考。通常说,我们甚至都不像考虑页面。我们唯一应该关心的是展示数据。所以我们看着用户数据,想“客户端可能需要从用户那儿获取什么数据或关系呢”或者,“什么信息是与用户有关的呢?”一些明显的信息例如他们的姓名,电子邮件,网址等。这就是直接与用户关联的数据。

        但是关系又是如何的呢?这会是像用户的帖子,评论,所喜欢的文章,所属于的团体等的数据。再次强调,不要去考虑是否有其他什么用途-在前端的环境中获取用户,然后拉取他们的组。在这儿,这不是一个与讨论相关的问题。事实上,如果显式,隐式或其他抽象关系适用于给定的对象类型,那你通常应该允许访问该数据,除非有更好理由谁服你不做。为什么?很大部分是因为我们真的不知道客户是需要做什么或者什么是最直观的做事方式。相对来说,把这些关系放到我们的图中是比较“便宜”的,而前端开发人员则试图准确地确定他们需要获取什么和从哪里得到好处,尤其是当事实证明这里存在被遗漏了的关系时。如果你是正在构建一个将用于外部的API,那这点就更加重要了,因为那时你就真的不知道他们需要做什么了。

        做这个的另一个好方法是,考虑下你将如何有逻辑地绘制一个包含一个单一的对象类型的框/圆圈和连接它们的线的关系地图。比如说,我们的例子可能看起来像这样:


构建更好的GraphQL API:用图思考_第2张图片

        提示:你的GraphQL图不必去反映你的数据库的表。事实上,它很多时候是不会的。比如,一般来说,你不想让你的连接表拥有一个对象类型,除非它们可以被有逻辑地计算出它们自己所包含信息的个体(除了外键)。

        接下来的一件事是要认识到关系是双向的。所以一个用户不仅可以有很多评论,而且一个评论属于一个用户。即是说,你应该在用户类型和评论类型上都表达这种关系。回到我们上面的图表,每一条线连接两个对象/类型。也意味着,每个类型应该有一个字段指向位于行的另一端的类型。

        希望上面的方法能帮助你实现从端思考转变到从图思考。

你可能感兴趣的:(构建更好的GraphQL API:用图思考)