关于图形的思考
¥Thinking in Graphs
它一路向下都是图[^1]
¥It’s Graphs All the Way Down1
使用 GraphQL,你可以将业务字段建模为图形
¥With GraphQL, you model your business domain as a graph
图形是对许多现实世界现象进行建模的强大工具,因为它们类似于我们的自然心理模型和对潜在过程的口头描述。使用 GraphQL,你可以通过定义结构将业务字段建模为图形;在你的结构中,你定义不同类型的节点以及它们如何相互连接/关联。在客户端,这创建了类似于面向对象编程的结构:引用其他类型的类型。在服务器上,由于 GraphQL 仅定义接口,因此你可以自由地将其与任何后端(新的或旧的!)一起使用。
¥Graphs are powerful tools for modeling many real-world phenomena because they resemble our natural mental models and verbal descriptions of the underlying process. With GraphQL, you model your business domain as a graph by defining a schema; within your schema, you define different types of nodes and how they connect/relate to one another. On the client, this creates a pattern similar to Object-Oriented Programming: types that reference other types. On the server, since GraphQL only defines the interface, you have the freedom to use it with any backend (new or legacy!).
共享语言
¥Shared Language
命名事物是构建直观 API 的一个困难但重要的部分
¥Naming things is a hard but important part of building intuitive APIs
将 GraphQL 结构视为你的团队和用户的一种富有表现力的共享语言。要构建良好的结构,请检查你用来描述业务的日常语言。例如,让我们尝试用简单的英语描述一个电子邮件应用:
¥Think of your GraphQL schema as an expressive shared language for your team and your users. To build a good schema, examine the everyday language you use to describe your business. For example, let’s try to describe an email app in plain English:
-
一个用户可以拥有多个电子邮件账户
¥A user can have multiple email accounts
-
每个电子邮件账户都有一个地址、收件箱、草稿、已删除项目和已发送项目
¥Each email account has an address, inbox, drafts, deleted items, and sent items
-
每封电子邮件都有发送者、接收日期、主题和正文
¥Each email has a sender, receive date, subject, and body
-
用户无法发送没有收件人地址的电子邮件
¥Users cannot send an email without a recipient address
命名事物是构建直观 API 的一个困难但重要的部分,因此请花时间仔细考虑什么对你的问题域和用户有意义。你的团队应该对这些业务字段规则形成共同的理解和共识,因为你需要为 GraphQL 结构中的节点和关系选择直观、持久的名称。尝试想象你想要执行的一些查询:
¥Naming things is a hard but important part of building intuitive APIs, so take time to carefully think about what makes sense for your problem domain and users. Your team should develop a shared understanding and consensus of these business domain rules because you will need to choose intuitive, durable names for nodes and relationships in the GraphQL schema. Try to imagine some of the queries you will want to execute:
获取我所有账户收件箱中未读电子邮件的数量
¥Fetch the number of unread emails in my inbox for all my accounts
{
accounts {
inbox {
unreadEmailCount
}
}
}
获取主账户前 20 草稿的 “预览信息”
¥Fetch the “preview info” for the first 20 drafts in the main account
{
mainAccount {
drafts(first: 20) {
...previewInfo
}
}
}
fragment previewInfo on Email {
subject
bodyPreviewSentence
}
业务逻辑层
¥Business Logic Layer
你的业务逻辑层应该充当执行业务域规则的单一事实来源
¥Your business logic layer should act as the single source of truth for enforcing business domain rules
你应该在哪里定义实际的业务逻辑?你应该在哪里执行验证和授权检查?答案:在专用的业务逻辑层内。你的业务逻辑层应该充当执行业务域规则的单一事实来源。
¥Where should you define the actual business logic? Where should you perform validation and authorization checks? The answer: inside a dedicated business logic layer. Your business logic layer should act as the single source of truth for enforcing business domain rules.
在上图中,系统的所有入口点(REST、GraphQL 和 RPC)都将使用相同的验证、授权和错误处理规则进行处理。
¥In the diagram above, all entry points (REST, GraphQL, and RPC) into the system will be processed with the same validation, authorization, and error handling rules.
使用旧数据
¥Working with Legacy Data
更喜欢构建一个描述客户端如何使用数据的 GraphQL 结构,而不是镜像旧数据库结构。
¥Prefer building a GraphQL schema that describes how clients use the data, rather than mirroring the legacy database schema.
有时,你会发现自己使用的旧数据源无法完美反映客户使用数据的方式。在这些情况下,更喜欢构建一个描述客户端如何使用数据的 GraphQL 结构,而不是镜像旧数据库结构。
¥Sometimes, you will find yourself working with legacy data sources that do not perfectly reflect how clients consume the data. In these cases, prefer building a GraphQL schema that describes how clients use the data, rather than mirroring the legacy database schema.
构建 GraphQL 结构来表达 “how” 而不是 “what”。然后,你可以改进实现细节,而不会破坏与旧客户端的接口。
¥Build your GraphQL schema to express “how” rather than “what”. Then you can improve your implementation details without breaking the interface with older clients.
一步一步来
¥One Step at a time
更频繁地获得验证和反馈
¥Get validation and feedback more frequently
不要尝试一次性对整个业务字段进行建模。相反,一次只构建一个场景所需的结构部分。通过逐渐扩展结构,你将更频繁地获得验证和反馈,以引导你构建正确的解决方案。
¥Don’t try to model your entire business domain in one sitting. Rather, build only the part of the schema that you need for one scenario at a time. By gradually expanding the schema, you will get validation and feedback more frequently to steer you toward building the right solution.
Footnotes
-
”一路向下的海龟” 是无限回归问题的一种表达。
¥“Turtles all the way down” is an expression of the problem of infinite regress. ↩