已经会CRUD了,还要学什么?
再来和上一篇一样是介绍一些个人觉得在GraphQL里比较花俏的操作,虽然说是花俏,但使用的恰当的话同样可以帮助我们更好的维护程式
不学会怎样吗?
其实当初笔者在学习GraphQL时,直接跳过了上一篇和这一篇提到的内容,就开始使用GraphQL建立后端的Server了,也是在一段时间后才回来补这段GraphQL的技术(知识),所以如果读者非常期待(急着)能看到结果的话,可以直接跳过上一篇和这一篇直接进入实战环节
Variables
why use?
还记得我们在query时可能会遇到需要把某一个值传入吗?其实,在实作时基本上我们一定都会使用到Variables,下面会举个例子,如下面这段code,看起来只是很简单的透过一个id去查询结果,但实际上如果我们要改变id的内容该怎么做?
query { meal(id:"58811ae5-1471-4366-844b-2886b3abccf1"){ id itemName price }}
在想改变id要怎么做前,先来看一个例子看完之后会解答原本的疑惑,在实际的应用中,可能会遇到很複杂的query,一次要传数个不同的值且型别也皆不相同的状况发生,例如,要做出一个可以同时搜寻金额的区间,餐点的种类,甚至连是否为限量商品的状况就会变成以下的範例
看完后是否有一种天啊要传太多东西了吧,此外,还有最重要的问题是,我的值已经写死了,还是没办法改变呀!这完全不符合实际的需求.因此,我们需要使用Variables来帮我们解决
可以看到在左下角的Query variables的区块内有一个Json格式的内容就是我们可以"弹性的调整"传入内容,而query内原先的字串,数值等内容已经被替换成了变数(就是看到以$开头的$minPrice及$category等)
此外Variables还可以加上default值,可能在搜寻时,开发者希望使用者在没有特别设定金额的情况下,不要推荐一千元以上的餐点,那么可以这么做,在maxPrice定义它的default值为1000,不过当下面的Query variables一但有传值进来的话,那么传进来的值将会取代default的1000
範例code:
query ( $minPrice: Int $maxPrice: Int=1000 $category: String $isLimitedEdition: Boolean) { mealsByMoreCondition( minPrice: $minPrice maxPrice: $maxPrice category: $category isLimitedEdition: $isLimitedEdition ) { id itemName price }}
Variables小结
笔者认为它基本上是在使用query传入参数时,必然会遇到的问题,default的部分可能还是要真的遇到一些比较特别的情境再使用会比较恰当一些
Directives
why use?
有没有遇过一种情境是,前端在同一个页面时,可能会因为他的使用者权限比较高而打了a+b api,但当他权限比较低时就只要打a api呢?依照传统的做法,我们可以会再前端写类似这样的东西
// 前端useEffect(() => { if (user.permissions === 5) { const mealsResponse = await callMeals({ endpoint: 'api/meals' }); const usersResponse = await callUsers({ endpoint: 'api/users' }); ... doSomething callUsersAndMeals() } else { const mealsResponse = await callUsers({ endpoint: 'api/meals' }); ... doSomething } }, []);
虽然看似很美好,但其实在同一个页面这种依照权限判断的事情,我们却要把它拆分成两只api,是有那么一些麻烦,如果把权限拆的更碎那可能会更可怕,因此我们可以靠Directives来帮我们解决问题
这个是把havePermissions填入false的
这个则是把havePermissions填入true的
範例code:
# Write your query or mutation herequery ($havePermissions:Boolean!){ meals{ id itemName } users @include(if: $havePermissions){ id firstName lastName }}
Directives小结
如此一来我们可以只透过只写一只api并且搭配Directives达成我们的目的,笔者自己再开发的时候,蛮习惯用来处理权限或是白名单之类的问题,不过如果当判断状况太多太混乱的时候,还是可以考虑把状况拆清楚,不要过度的滥用导致维护成本增加
Enumeration Types
why use?
这个东西对于熟悉强型别语言的人可能多多少少都有用过,不熟悉的话没关係,这边还是会完整的介绍一次
基本上笔者对他的了解为,强烈且硬性的规範传入值,举个例子,今天在传入meal的category时,原先前端的设计只有麵食跟饭食及饺类可以做分类,但使用者却不知道用了什么方式传了一个坚果给后端,让这值会让前后端都很难办,很有可能都会大大的影响到我们的前端的显示画面,因此我们需要Enumeration Types来严格的把控这件事情
这个时候我们就来使用一个新的Type Declarationenum
,透过以下方式定义完成之后可以来看一下Playground会怎么告诉我们这件事情
enum CategoryEnum { "麵食" pasta "饭食" rice "饺类" dumpling}# inputinput MealInput { itemName: String! price: Int! isStopSelling: Boolean! category:}
很清楚的告诉我们category只能是pasta,rice或dumpling的其中一个
来故意新增一个nut看看,如我们的预期被挡下来了
Enumeration Types小结
透过Enumeration Types让我们的程式可以更加严谨,不会收到一些不理想的值,甚至是前端的工程师在开发时,也可以透过enum定义的内容了解更多事情,不过使用时请一样要谨慎的使用,毕竟影响範围很大,可能会让前端完全没办法新增或是更新资料,使用时请务必小心
以上若有错误,还请不吝指教.谢谢
GraphQL小结
基本上GraphQL说到这边已经差不多了,可以看到它有许多很弹性的语法及应用方式,其实官方网站还有更多,只是笔者也没有再更深入的了解了,期待未来能看到不同人的分享了解更多神奇的操作
再来就要进入实战的部分了,不过笔者可能要过一阵子才会补完实战的部分了.....