GraphQL 是一种查询语言和运行时执行的数据查询和操作系统。它使应用程序能够在一个接口下以更高效、强大和灵活的方式查询和操纵数据。
然而,GraphQL 也有一些挑战,其中一个是构建健壮的 GraphQL API。在实现 GraphQL API 时,需要考虑一些问题,例如应对恶意查询、优化性能、异常处理等。
本文将指导您如何构建健壮的 GraphQL API,增强它的安全性和可靠性。
防止恶意查询
在 GraphQL 中,客户端可以使用查询语言来自定义其请求的数据结构。这是 GraphQL 强大和灵活的一面,但也可能导致客户端执行包含多个嵌套字段和深层次查询的恶意查询,从而使服务器资源被攻击。
为防止这样的攻击,可以实施以下措施:
1. 查询深度限制
可以限制查询的深度,这可以确保查询的复杂度不能太高。可以使用 GraphQL 的 graphql-depth-limit
或者 graphql-query-complexity
这样的库来实现。
例如:
-- -------------------- ---- ------- ----- ---------- - ------------------------------- ----- - ------------------------- - - ----------------------------------------- ----- ------ - --- -------------- --------- ---------- ---------------- - -------------- -------------------------------- -- ---
上述代码中的 depthLimit
和 createComplexityLimitRule
分别限制了查询的深度和查询的复杂度。
2. 字段限制
GraphQL 客户端还可以请求包含多个字段的查询,这可能导致服务器资源被消耗殆尽。可以使用 GraphQL 的 graphql-fields-list
库限制客户端请求的字段。
例如:
const getFields = require('graphql-fields-list'); const resolver = (parent, args, context, info) => { const fields = getFields(info); // do something with fields }
上述代码中,我们使用 graphql-fields-list
库来获取客户端请求的字段列表,以便服务器可以只响应需要的字段。
优化性能
性能是建立健壮的 GraphQL API 的关键,因为它会影响用户体验。
1. 数据缓存
GraphQL API 可以从缓存中获取数据而不是每次请求都从数据库中检索,以提高性能。可以使用 graphql-cache
等库轻松地实现 GraphQL 数据缓存。
例如:
-- -------------------- ---- ------- ----- - ---------- - - ------------------------------------- ----- ----- - --- ------------ -- ---------- --- ----- ------ - --- -------------- --------- ---------- ------ ---
上述代码中,我们使用 RedisCache 作为 ApolloServer 的缓存选项。
2. 批处理
GraphQL 客户端可能会发送多个查询请求,这可能导致性能问题。可以使用批处理解决此问题,批处理可以将多个查询请求组合为一个请求。
例如:
-- -------------------- ---- ------- ----- ------ - --- -------------- --------- ---------- -------- - --- --------------- ---- ----------------------------- --- -- ---
上述代码中,我们使用 BatchHttpLink 将多个请求组合成一个请求发送到 GraphQL API。
异常处理
GraphQL API 在面对意外情况时需要正确地处理异常,这有助于提高 API 的可靠性。
1. GraphQL Errors
我们应该为 API 中可能发生错误的地方定义错误类型。
例如:
-- -------------------- ---- ------- ----- - ----------- - - ------------------------- ----- -------- - ----- -------- ----- -------- -- - --- - ----- ------ - ----- ------------------ ------ ------- - ----- ------- - ----- --- ----------------- ----- ---------- ------------------- - -
上述代码中,我们在 resolver 中捕获某些错误,并使用 ApolloError
抛出有意义的错误。
2. Error Handling Middleware
我们还可以编写自定义错误处理程序来处理 GraphQL API 中的错误。这种方式可以避免在 resolver 中重复编写错误处理逻辑。
例如:
-- -------------------- ---- ------- ----- - ------------ - - --------------------------------- ----- ------- - ------------------- ----- --- - ---------- ----- ------ - --- -------------- --------- ---------- --- ------------- ---- ---- ----- -- - -- --------- --- -------------- - ---------------------- -------- ------------ ----- -------------------- --- - ---- - ---------- - --- ------------------------ --- --- ------------ ----- ---- -- -- -- --------------- ------ ----- -- -------------------------------------------- --
上述代码中,我们使用 express 的错误处理中间件来处理应用程序中的任何错误。当 ApolloError 发生时,我们将响应发送到客户端。
结论
通过这篇文章,我们了解了如何构建健壮的 GraphQL API,包括如何防止恶意查询、优化性能和处理异常,并通过代码示例演示了这些技术。我们希望这些技术可以帮助您构建高效、可靠且健壮的 GraphQL API。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/677272fa6d66e0f9aad94cef