首次使用Rails进行GraphQL

这篇文章的内容 (Zhè de

我在Rails中從事開發工作。GraphQL是什麼?作為一個相對初學者,我必須快速在工作中實現它,所以我決定一邊記錄一邊創建它。

在这篇文章中,我们将介绍如何将GraphQL集成到Rails应用程序中,并涵盖了准备获取数据的步骤。接下来的内容将逐渐进行记录。

    • 初めてのGraphQL with Rails ②(Apollo Client編)

 

    順次追加予定…

GraphQL是什么?图是指什么?

听说有一个叫做图论的理论。在这个理论中,我们通过将数据的结构用点和线连接起来的方式来理解。这种结构被称为图(Graph)。GraphQL中的最后一个QL是将查询语言(Query Language)添加到这个图中,所以我们称之为GraphQL。

▼关于Graph理论本身,请点击此处。

为什么要使用GraphQL?

目前,作为数据库和客户端之间交流的方式,常见的是使用名为RESTful API的方法。据说RESTful API的缺点是会过度获取数据。而GraphQL能够克服这个弱点,可以仅获取所需的数据。

RESTful API指的是一种用于建立Web服务的架构风格。它具有以下特点:1)通过统一的接口进行通信;2)无状态、可缓存的传输;3)支持多种数据格式,例如JSON和XML;4)分层的客户端-服务器模型。

然而,RESTful API也存在一些缺点。例如,它可能需要多次请求来满足客户端的需求,导致网络开销增加。同时,API的设计也可能变得复杂,难以维护。

与RESTful API相比,GraphQL具有独特的特点。GraphQL是一种查询语言,允许客户端按需获取所需的数据。它通过单个请求来返回客户端需要的数据,减少了不必要的网络开销。GraphQL还支持强大的类型系统,提供了更好的灵活性和可扩展性。另外,GraphQL的优点还包括可视化的查询调试工具和版本控制功能。

总而言之,GraphQL相较于RESTful API在部分方面具有更好的性能和灵活性。

超取数据是什么意思?

GraphQL存在的地方

在理解GraphQL时,了解GraphQL在应用程序结构中的位置是非常重要的。

Image from Gyazo

在数据库和设备之间,使用GraphQL进行了记录。

制作GraphQL API所需之物

我理解为了实现GraphQL API所需的东西有以下三个方面。

名前役割クエリ言語GraphQLサーバーへの問い合わせ内容を記載した言語スキーマ言語GraphQLサーバーでのデータの型を記載した言語リゾルバ問い合わせを実行するメソッド

这里有一些非常优秀的现有文章。特别是下面的这篇文章对理解非常有帮助,我会附上链接。

在这里,我们只需要理解GraphQL是由上述的三个部分“查询”、“数据类型”和“查询执行”组成的。

那么,在Rails中应该怎么做呢?

如果要使用Rails来表示上述内容,一个方便的Gem是graphql-ruby。在本次中我们也将使用它。以下是有关graphql-ruby的实现文章。

如果您想了解GraphQL的原始记录方法,我认为您可以尝试查阅上述文章或下面的官方教程等资源。

这篇文章的参考资料

在本篇文章中的实现主要参考了本文和graphql-ruby官方网站的内容。

这次展现的内容

我想用GraphQL来表示从用户表中获取“用户列表”和“用户详细信息”的过程。

usersidintegernamestringemailstring

首先

首先,我们将学习如何使用graphql-ruby。

# Gemfile
gem 'graphql'
group :development do
  gem 'graphiql-rails'
end

# ターミナル
$ bundle install
$ rails g graphql:install

使用上述命令将会生成大量的文件。以下是已生成的文件列表。

create  app/graphql/types
      create  app/graphql/types/.keep
      create  app/graphql/portraits_uploader_schema.rb
      create  app/graphql/types/base_object.rb
      create  app/graphql/types/base_argument.rb
      create  app/graphql/types/base_field.rb
      create  app/graphql/types/base_enum.rb
      create  app/graphql/types/base_input_object.rb
      create  app/graphql/types/base_interface.rb
      create  app/graphql/types/base_scalar.rb
      create  app/graphql/types/base_union.rb
      create  app/graphql/types/query_type.rb
add_root_type  query
      create  app/graphql/mutations
      create  app/graphql/mutations/.keep
      create  app/graphql/mutations/base_mutation.rb
      create  app/graphql/types/mutation_type.rb
add_root_type  mutation
      create  app/controllers/graphql_controller.rb
       route  post "/graphql", to: "graphql#execute"
      create  app/graphql/types/node_type.rb
      insert  app/graphql/types/query_type.rb
      create  app/graphql/types/base_connection.rb
      create  app/graphql/types/base_edge.rb
      insert  app/graphql/types/base_object.rb
      insert  app/graphql/types/base_object.rb
      insert  app/graphql/types/base_union.rb
      insert  app/graphql/types/base_union.rb
      insert  app/graphql/types/base_interface.rb
      insert  app/graphql/types/base_interface.rb
      insert  app/graphql/アプリ名_schema.rb

在生成的文件中,我认为这两个文件在理解graphql-ruby的结构上特别重要。

app/graphql/types/query_type.rb
app/graphql/アプリ名_schema.rb

整个过程

根据graphql-ruby官方网站的教程,据说在Rails中进行GraphQL服务器查询所需的步骤有以下3个。

    • 型を決める

 

    • それらの型とスキーマをつなぐ

 

    クエリをスキーマで実行

我会一个一个地逐个检查。

制作模板文件

在Rails中,可以使用命令来生成GraphQL的类型文件。

$ rails g graphql:object User

create  app/graphql/types/user_type.rb

以下是生成的文件内容。

module Types
  class UserType < Types::BaseObject
    field :id, ID, null: false
    field :name, String, null: false
    field :email, String, null: false
    field :created_at, GraphQL::Types::ISO8601DateTime, null: false
    field :updated_at, GraphQL::Types::ISO8601DateTime, null: false
  end
end

如果已经存在User模型,它会自动生成相应的类型。一开始

$ rails g graphql:object User name:String email:String

但是由于已经有了User模型,所以name列和User列各产生了两个。

模式文件

为了执行上述所定义的内容,需要一个文件。
以下是创建的模式文件。

module Type
  class QueryType < GraphQL::Schema::Object

    # フィールド(:user)の説明と引数を記載します。
    field :user, Types::UserType, null: true do
      description "Find User by ID" #省略可
      argument :id, ID, required: true
    end

    # 実行のコマンド(リゾルバ)を書きます
    def user(id:)
      User.find(id)
    end

    def users(page: nil, items: nil)
      User.all
    end
  end
end

学んでいく必要があります。最初は既存のソースをコピーしながら進めることになると思いますが、その過程で理解できない単語やメソッドが多く現れるでしょう。理解できないことは地道に学んでいく必要があります。

    graphql-rubyのガイドページ

可以在互联网上进行搜索。

为了理解上面的代码,我做了以下的调查。

领域 yù)

类方法。是一种从数据库中提取数据的方式。对象和接口都具有字段。(有关对象和接口的详细信息,请查看名称部分的链接。)

field的写法如下所示(也有其他写法。请参考field的文档以获取详细信息)。

field :name, String, null: true do
  description "The name of this thing"
end

在代码块的第一行中,包含了field :字段名称,类型的位置以及是否可能为空的信息。

注意点是,如果定义了与字段同名的方法(解析器),那么实际返回的将是解析器的值。
例如,稍微修改一下之前的代码。

 field :user, Types::UserType, null: true do
   argument :id, ID, required: true
 end

 def user(id:)
   # User.find(id) ここを書き換え
   User.where(name: "山田太郎")
 end

根据我所选择的,返回的将是山田太郎先生的数据。

论点

这是用于搜索和调用数据的参数。例如

field :user, Types::UserType, null: true do
   argument :id, ID, required: true
end

通过定义参数id,可以进行如下的论证:

{
  user(id: 1) {
    name
    email
  }
}

可以写一个查询来调用具有id为1的用户。
此外,还包含了以下的写法。

{
  customers(first: 5) {
    name
    outstandingBalance
  }
}

{
  posts(startYear: 2018) {
    id
  }
}

在Rails中似乎可以在这里定义order、limit和搜索键等。

页面、项目等

目前尚不清楚(抱歉)。不过,graphql-ruby似乎专门用来处理分页,所以可能是与分页设置相关。如果我理解有误,我会进行更正。如果我明白了,我会添加附注。

我也会附上一篇关于类似实现的文章。

根据类型确定的根源

在graphql-ruby官方网站的教程中,写道”在创建模式文件之前,请确定入口点(查询根)”。

翻译为中文:

意思是,每个模式似乎都有一个根类型。

似乎GraphQL本身有一个概念叫做”根类型”(虽然在GraphQL官方网站上没有找到相关术语,但在书籍《初识GraphQL》中提到了”根类型”这个词)。

那就是,

$ rails g graphql:install

生成此文件时所记录的内容。

app/graphql/アプリ名_schema.rb

这个文件是这样写的。 (Zhè gè shì xiě de.)

class AppNameSchema < GraphQL::Schema
  # required
  query Types::QueryType
  # optional
  mutation Types::MutationType
  subscription Types::SubscriptionType
end

以下是有关数据的“查询(query)”,“变更(mutation)”,“订阅(subscription)”在各个架构中的位置。类型位置(例如Types::QueryType)在根类型文件中相对位置给出,因此我理解这是为了事先确定“入口点(根位置)”。

执行模式

这里虽然对于graphql-ruby的查询执行有一些说明,但通常使用graphql-ruby以外的库来进行。

在.graphql-ruby网站上

    • Relay

 

    • Apollo Client

 

    GraphQL.js Client

作为一个例子被提到。
在工作中使用了Apollo Client,但由于可能变得很长,我想将其记录在另一篇文章中。

直到现在为止的感想

一开始开始调查之后,发现非常深奥…
虽然这篇文章也变得有点不完整,对此感到抱歉,但是一旦理解了,似乎非常方便,所以我希望能够进一步学习一下。

bannerAds