继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

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

千岁不倒翁
关注TA
已关注
手记 362
粉丝 60
获赞 386
原文出处              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 注册。


打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP