错误作为数据处理
使用联合类型表示不同的响应场景
在 GraphQL 中的联合类型是表示单个字段中多种数据类型的一种极好的方法。这在处理不同类型的响应时极为有用,例如成功和错误情况。通过利用联合类型,开发者可以创建一个灵活且具有表现力的API,优雅且高效地处理不同场景。
GraphQL的一个核心特性是其内置的错误处理机制,它使用响应中的errors
数组来表示请求过程中发生的任何错误。然而,并不是所有错误都希望包含在这个数组中。如果我们遵循“错误即数据”模式,errors
数组应该用于系统错误——那些通常会导致HTTP 500错误的情况。
系统错误可能包括以下情况
- 服务器崩溃
- 未处理的异常
- 资源耗尽(例如,内存或CPU)
这些错误通常是不预期的,客户端无法优雅地处理它们。因此,它们应该在服务器端进行记录和监控,而客户端应该显示通用的错误消息。
另一方面,所有其他业务逻辑错误,可以作为响应联合内的已知响应类型的一部分。这使得客户端可以明确地处理这些错误,提供更好的用户体验和可维护的代码。
在这个示例中,我们将来看一个处理用户购物车并创建订单的突变(mutation)。这个突变可能的成功响应包括成功创建订单、库存不足或无效的支付方式。我们将使用联合类型来表示这些不同的响应场景。
union CheckoutResponse =Order| InsufficientStockError| InvalidPaymentMethodErrortype Mutation {checkout(paymentMethod: ID!): CheckoutResponse}type Order {id: ID!items: [OrderItem!]!totalPrice: Float!status: String!}type OrderItem {id: ID!product: Product!quantity: Int!price: Float!}type Product {id: ID!name: String!price: Float!}interface CheckoutError {message: String!}type InsufficientStockError implements CheckoutError {message: String!product: Product!availableStock: Int!}type InvalidPaymentMethodError implements CheckoutError {message: String!paymentMethod: ID!}
在上面的模式中,checkout
mutations 返回一个 CheckoutResponse
联合类型,可以是以下类型之一: Order
、InsufficientStockError
或 InvalidPaymentMethodError
。客户端可以分别处理这些情况,确保API设计清晰明了。
现在,让我们看看一个示例 操作 和可能的响应处理:
mutation OrderCheckout($payment: ID!) {checkout(paymentMethod: $payment) {... on Order {iditems {product {name}quantityprice}totalPricestatus}... on InsufficientStockError {messageproduct {name}availableStock}... on InvalidPaymentMethodError {messagepaymentMethod}}}
在这个 mutation 中,客户端为可能的响应类型请求不同的 字段:
- 对于成功的订单创建(
Order
),客户端获取订单详情,包括项目、总价和状态。 - 对于库存不足错误(
InsufficientStockError
),客户端获取错误消息、受影响的商品和可用库存信息。这些信息可用于显示用户友好的错误消息并建议替代操作,例如更新购物车。 - 对于无效的支付方式错误(
InvalidPaymentMethodError
),客户端获取错误消息和问题支付方式ID。这可以用来通知用户问题并提示他们更新支付信息。
通过使用 CheckoutResponse
联合类型,API提供了一种干净且灵活的方式,来处理结账过程中可能出现的不同响应场景。这让客户端能够分别处理每种情况,为 operation 响应提供强类型,并提升开发者体验。