我有一个关于使用GraphQL进行模式驱动开发的经历
概述
在公司引入GraphQL时,我们尝试了使用模式驱动开发的开发方式。
我们希望能够介绍一下我们具体进行了哪些开发工作,以及这样做的效果如何。
这篇文章是在上次的LT中介绍的内容上稍加修改和修正。
在GraphQL中,以模式驅動的方式進行開發
在引入GraphQL时,有一个优点是可以实现“以模式为驱动”。
关于基于模式的开发,请查阅Qsona先生的资料更详细。
在构建GraphQL时有两种方法,分别是代码优先和模式优先。
“Code First” 是一种用 GraphQL 代码定义 API 的模式,通过定义 GraphQL 类型并将它们组合来生成模式。为了定义模式,我们需要定义 GraphQL 类型并使用它们来定义查询。
“Schema-First” 是一种使用GraphQL模式来定义API并生成API的方法。为了定义模式,我们使用GraphQL的模式定义类型,并通过组合这些类型来定义查询。
这次我们引入了GraphQL Ruby,并通过代码优先的方法来构建API。
版本信息
Ruby:3.0.2
Ruby on Rails:6.1
graphql-ruby:1.13.16
使用GraphQL进行实际的基于Schema的开发步骤。
1. 准备一个Resolver
在这个阶段,我们需要与前端团队就传入参数和返回数据进行确认和协商。
class ContentsResolver < GraphLQ::Schema::Resolver
type ObjectTypes::ContentType.connection_type, null: false
argument :keyword, String, required: false
argument :author_id, ID, required: false
def resolve(keyword: nil, author_id: nil)
end
end
module ObjectTypes
class ContentType < BaseObject
field :press_id, String, null: true
field :is_published, Boolean, null: false
field :category_name, String, null: true
end
end
实施一个返回虚拟数据的实现。
为了临时实现逻辑,我将创建一个只返回匹配数据类型的虚拟数据的实现方法。
class ContentsResolver < GraphLQ::Schema::Resolver
argument :keyword, String, required: false
argument :author_id, ID, required: false
# TODO: ロジックは後で実装
def resolve(keyword: nil, author_id: nil)
+ Content.first(10)
end
end
module ObjectTypes
class ContentType < BaseObject
field :press_id, String, null: true
field :is_published, Boolean, null: false
field :category_name, String, null: true
+
+ # TODO: ロジックは後で実装
+ def press_id
+ "1"
+ end
+
+ # TODO: ロジックは後で実装
+ def is_published
+ true
+ end
+
+ # TODO: ロジックは後で実装
+ def category_name
+ "category_name"
+ end
end
end
3. 合并
当在新建的API情况下,我们会从前端接收到反馈并将其作为虚拟数据来实现,然后将其合并到代码中。
同时进行前端和后端开发。
由于从前端现在能够处理返回虚拟数据的GraphQL服务器,所以请基于该数据继续实施。
在后端,我们将继续推进刚才创建的临时方法的内部实现。
如果在前端实现过程中需要额外的数据或后端处理,我们会与您商讨或者请求前端工程师亲自修正代码,然后由后端进行审查,以此推进工作。
好的方面是
在以往开发RESTful API的过程中,确定一个完整的规范需要花费很多时间,而且在后端API实现完成之前,前端可能会空闲下来,因此会产生一些”等待实现”的时间。然而,引入了基于模式驱动的开发方法后,我们发现这段时间有所减少。
另外,如果后端实现过程中遇到了困难,就不再感到必须“让前端的人等待”的奇怪压力,因此实现变得更加轻松了。
此外,由于引入了GraphQL,前端和后端之间可以使用Schema和Type作为共同语言进行交流,这是一个很好的改变,以前我们需要仔细查看JSON格式的键等。
課題意識和反思
这次我们主要在后端进行了模式的设计。结果是在前端实现阶段,很难想象前端如何使用该模式和数据。因此,在前端实现阶段,API的设计发生了变更和修正。
如果发生这种情况,前端希望能够自行修改API,但由于此次实现是在Ruby中进行的,因此在进行修改时也需要一些后端知识。
前端和后端互相具备一定的对方知识,对开发的顺利进行有利。