为了账号安全,请及时绑定邮箱和手机立即绑定

使用GraphQL查询参数来设计强大的API

标签:
设计
原文出处              Designing Powerful APIs with GraphQL Query Parameters            

           

GraphQL API 设计的学习与最佳实践

GraphQL 查询提供了一种有效的方式来获取数据,甚至可以跨越多种语言。这使得数据层上有很好的抽象层,但有时候需要更多,来满足现代应用程序对特殊数据的需求。

我们的 GraphQL API 通过暴露不同的请求参数,来让客户端控制数据,并给予开发者更好的体验(DX)。类似于我们的嵌套变更语法,这也被越来越多的公司采用。我们 Graphcool 很高兴可以在 GraphQL 社区分享这一强大的最佳设计实践 GraphQL API。

本文探讨了我们的部分 GraphQL API 功能,包含:

  • 过滤:通过用一个或多个匹配规则来过滤节点。

  • 排序:由一个字段来升序或降序集合。

  • 分页:在不同的页面中组合查询到的节点,包括前进或者向后查询。

过滤可以降低客户端的复杂度

你通常会想要查询数据的特殊部分。以一部电影的数据库为例子,你可能会查询在某个特定日子后的电影或者是有特别名字的。当然你总是可以查询所有的电影,并在客户端侧过滤他们,而这会导致不必要的数据--这是 GraphQL 可以避免的。

这是个使用 GraphQL 的好例子 查参!通过添加 filter 参数到查询里面,以上场景可以被迅速解决。如果你想要名称是《黑暗骑士》 的电影,你只需要在 filters 里面指定 title 字段就好了:

query darkKnightMovie {
  allMovies(filter: {
    title: "The Dark Knight"
  }) {
    releaseDate
  }
}

通过名称过滤可以有效的获取单个电影。实际上,过滤系统比这还要更加强大,因为它编码 布尔代数。通过逻辑操作可以有更高层次的表现。

你可以在过滤条件中结合 ORAND 操作,来选择多部你感兴趣的电影。例如,如果你想要查询电影《盗梦空间》以及2009年后发布的名称是《黑暗骑士》的电影,你可以用 OR 来结合这两个查询条件。

query combineMovies {  allMovies(filter: {    OR: [{      AND: [{        releaseDate_gte: "2009"
      }, {        title_starts_with: "The Dark Knight"
      }]
    }, {      title: "Inception"
    }]
  }) {    title
    releaseDate
  }
}

在数据需求上,通过提供 filter 查询参数,服务端做着繁重的工作,同时客户端保持完全的控制。这就生成了清晰并且有表象的 API ,并分离前后端之间的顾虑。

表达甚至更加复杂的数据需求

一个经典的需求就是数据排序 - 这又是通过服务端要比客户端好的地方。让我们结合数据排序和过滤器。

这次我们想要2009年后发布的电影的演员。filter 参数对这类请求有着强大系统。我们可以用 movies_some 并嵌套  releaseDate_gte:2009,这个含义是我们想要的演员,其饰演的_部分_电影能够满足嵌套条件。

最重要的是,我们通过 orderBy: name_ASC 字段来排序。

query actorsAfter2009 {
  allActors(    filter: {      movies_some: {        releaseDate_gte: "2009"
      }
    }    first: 3    orderBy: name_ASC
  ) {
    name    movies {
      title
    }
  }
}

像这样结合过滤器和排序参数,可以让你简单的表达甚至更加复杂的数据请求。我们也可以用 movies_none 或者 movies_all 来表示查找的演员的所有电影_没有_或者_全部_满足的这些条件。

如果你仔细看,还会在上面的查询中发现 first: 3 参数。让我们看看这是什么

在相同规格的页面上浏览数据

想象一下一个罗列电影及其演员的网站。你的数据可能包含数千部电影,每部都包含很多演员。一个典型的场景是一次只展示几部电影,并允许用户向前或向后查询浏览整个电影列表。

在这里,你可以在查询中镜像表示参数,只获取现在需要的数据,来替代一次性获取所有数据的做法。这再次大大地简化客户端需要的逻辑,并且减少需要发送的数据。这种方式也叫做offset-base pagination。一个甚至更先进的分页变种叫做 cursor-based pagination,这也是通过结合 firstafter 或者 lastbefore 来实现的。这里我们将重点关注偏移分页。

翻页参数与过滤器和排序无缝集成。通过这个方式,我们不再用简单的查询来满足复杂的请求。我们看看下面的查询是如何应用我们所学到的。我们展示2000年后发布的头两部电影,通过其发布时间来排序,并且对其演员名单排序。你自己看看:

query paginateMoviesAndActors($movieFirst: Int, $movieSkip: Int, $actorFirst: Int, $actorSkip: Int, $movieOrder: MovieOrderBy) {
  allMovies (
    filter: {
      releaseDate_gt: "2000"
    }
    orderBy: $movieOrder
    first: $movieFirst
    skip: $movieSkip
  ) {
    title
    actors(
      orderBy: name_ASC,
      first: $actorFirst,
      skip: $actorSkip
    ) {
      name
    }
    releaseDate
  }
}

你可以通过提供的查询变量来实践,看看他们有什么效果。例如,你可以设 movieSkip2movieOrdertitle_DESC,然后再查询。将会按照名字的降序返回第二页电影。

总结

我们精心设计 GraphQL APIs,让客户端应用有很好的灵活性和控制。通过不同的规则来 过滤排序,以及 分页 你的数据,你可以准确的表达你想要的数据,让后端找出来。.

你对我们的 API 有没有什么疑问?可以参与我们的 Slack 频道 来讨论,或者浏览 文档 获取更多信息。如果你还没有账户,可以在 这里 Graphcool 注册。


点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消