
2.4.4 传递输入类型
前面讨论了Query和Mutation操作的参数是一个或多个简单的数据类型,比如说商品的ID和购买数量等,这虽然已经可以满足很多查询操作的需要,但有时候查询操作需要传入的参数也属于复杂结构的数据,那么这时候就可定义一个输入类型(Input Type):
需求 扩展下单操作,使其可以支持一次购买多个商品,并且在订单中加入送货地址。
这个需求并不难做,开发者可以通过给前面定义的makeOrder操作增加参数的方法来实现。但是如果开发者想让“下单”操作有更好的扩展性和向前兼容性的话,可以在GraphQL中使用输入类型,也就是下面例子中的input关键字所定义的类型:

根据上面所定义的两个Input类型OrderInput和OrderItemInput,以及在Mutation中新定义的makeOrderV2,可以看到makeOrderV2只接受一个参数order: OrderInput,也就是前面定义的输入数据类型。把这两个操作放到一起,方便读者进行比较,实际项目中一般只需要makeOrderV2这种形式就够了。
动动手:给订单输入数据类型OrderInput增加一个字段:下单时间。
输入数据类型给GraphQL服务带来了更好的向前兼容性。读者可以发现,在给订单输入数据类型增加一个字段的过程中,无须修改makeOrderV2这个操作的Schema定义。如果新加入的数据类型不是必填项,这对客户端的实现是向前兼容的。也就是说,如果这个电商网站还有一些老的客户端没有及时更新,还不支持下单时间这个字段,尽管服务器已经开始支持这个新字段了,但老客户端还可以在不升级的情况下照常使用。当然用户使用老客户端创建的订单,就不包含下单时间这个数据了。
再来看看发送给服务器端的查询是什么样子的。在客户端发送下面的操作请求给makeOrderV2:


客户端拿到下单操作的返回数据后,可以酌情更新本地的数据。比如说用户成功购买了某种商品,那么这种商品的库存就要发生变化,这时候可以利用服务器端返回的最新库存(inStock)来更新本地库存。具体的实现细节会在后面的章节讨论。
使用输入类型还有另外一个好处,就是可以提供更好的重用性。
动动手:设计一个更新订单的操作。
这其实也是GraphQL对新建和更新两个操作的固定模式,和新建操作相比,更新操作只需要多提供一个订单ID,就可以解决问题。代码如下:
