我尝试使用GraphQL实现了一个鸡尾酒搜索服务

首先

你好。我平常使用 React 来实现前端。最近对 GraphQL 充满了兴趣,因为了解了除了 REST 之外的选择,使得技术选型更加广泛。我尝试使用 GraphQL 来实现了一些服务,最后我在下面列举了实际运行的成果。希望我的感想能够帮助你更加深入理解 GraphQL。

示例和代码

示例:https://liquor-react.netlify.com/
客户端源代码:https://github.com/yoneda/liquor-react-client
服务器源代码:https://github.com/yoneda/liquor-graphql-server

    • 2019年12月15日 追記

GraphQL サーバーのデプロイ先をGlitch からheroku に移行して表示速度を改善しました。

整个组织的结构

在寻找可用的免费数据时,我发现了一个名为RapidAPI的服务。在那里我找到了可以搜索酒和鸡尾酒的Cocktail DB API,所以这次我选择使用了它。客户端使用了React,服务器使用了GraphQL进行实现。GraphQL不仅可以连接数据库,还可以连接其他的REST API或者其他的GraphQL。通常我们会将GraphQL连接到数据库,但这次我连接了REST形式的RapidAPI。GraphQL可被视为BFF(后端适用的前端)的角色。图形化如下所示。

graphql.png

运用技术

这次使用的技术如下:
客户端:react、apollo-client、react-scripts、reach-router
服务器:express、express-apollo-server、superagent、nodemon

服务器端

我們使用 Express + ApolloServer 來實現伺服器端。在 ApolloServer 中,我們定義了結構並實現了相應的解析程序。我們根據 RapidAPI 返回的 JSON 定義了結構。查詢返回雞尾酒列表的操作如下所示。

  enum DrinkCategory{
    COCKTAIL
    COFFEE
    BEER
    OTHER
  }
  type Query{
    allDrinks(category: DrinkCategory): [Drink!]!
  }
  type Drink{
    id: ID!
    name: String!
    url: String!
    category: DrinkCategory
  }

客户

客户端使用React + ApolloClient进行实现。在React中发出GraphQL查询非常简单。只需要在组件根部设置GraphQL的URI,并使用useQuery Hooks来获取数据,仅需这两个步骤就可以连接到服务器。

我的实施感受

Apollo Client的高效缓存功能非常方便

Apollo Client会将来自服务器的获取结果缓存在本地。当从组件A获取blog文章后,如果从组件B尝试获取相同的文章,Apollo Client会直接访问缓存中的数据,并且不需要再次向服务器发送请求,所以显示速度很快。以前,这种实现是由Redux完成的(为A和B组件准备可以访问的Redux值。将获取的博客文章结果存放在Redux中,当B组件尝试获取时,从Redux中访问值)。使用Apollo Client,这个缓存功能是一开始就准备好的,无需自己编写大量代码。

减少验证的工作量

在用Node.js实现服务器端的时候,如果想要进行验证,就需要额外添加中间件。这里所说的验证是指检查请求的参数值的类型,以及检查该值是否为必需等过程。使用GraphQL可以确保客户端和服务器之间的类型,这使开发人员感到安心。

GraphQL使不需要太多请求次数。

RESTとGraphQLの特徴を比較すると、どちらがデータを効率的に取得できるかというと、私はGraphQLの方が優れていると考えています。特に、あるデータとその関連するデータを取得するような場面では、GraphQLが優れているようです。例えば、ブログ記事とその記事に対するコメントを取得するAPIを実装する場合を考えてみましょう。

GET /articles/:id
GET /articles/:id/comments

在REST中,自然地实现是发送两次请求,就像上面所示。(当然,也可以实现同时获取博客文章和其评论的方式。但是,如果按照REST的设计原则,将GET / POST / PUT / DELETE分配给一个资源,我认为上述设计更自然。)

query{
  article(id: $id){
    title
    body
    postedComments{
      comment
      user
    }
  }
}

GraphQL允许在一次请求中获取所需的字段,并且可以只获取所需的字段,而不会获取额外的无用字段,这样非常高效。我觉得GraphQL的设计能够高效地获取数据。

下次(计划)

因为这一次只是查询,所以下一次我想实现变更和用户认证。一旦实现了,我会在这篇文章中进行更新,或者发布一篇新文章!

广告
将在 10 秒后关闭
bannerAds