ruby on rails_如何设置Ruby on Rails GraphQL API

黄兴业
2023-12-01

ruby on rails

The author selected Free Press to receive a donation as part of the Write for DOnations program.

作者选择Free Press作为Write for DOnations计划的一部分接受捐赠。

介绍 (Introduction)

GraphQL is a strongly typed query language for APIs and a server-side runtime for executing those queries with your existing data. GraphQL allows clients to fetch multiple resources from the server in a single request by giving clients the ability to specify the exact data needed in the query. This removes the need for multiple API calls. GraphQL is language and database independent, and thus can be implemented in almost every programming language alongside any database of choice.

GraphQL是一种用于API的强类型查询语言,是一种服务器端运行时,用于对现有数据执行这些查询。 GraphQL使客户端能够指定查询中所需的确切数据,从而允许客户端在单个请求中从服务器获取多个资源。 这消除了对多个API调用的需要。 GraphQL是独立于语言和数据库的,因此可以与任何选择的数据库一起,以几乎每种编程语言实现。

In this tutorial, you will build a GraphQL-powered Ruby on Rails API for taking notes. When you are finished, you will be able to create and view notes from the API using GraphQL.

在本教程中,您将构建一个支持GraphQL的Ruby on Rails API来做笔记。 完成后,您将能够使用GraphQL从API创建和查看注释。

If you would like to take a look at the code for this tutorial, check out the companion repository for this tutorial on the DigitalOcean Community GitHub.

如果您想看一下本教程的代码,请在DigitalOcean社区GitHub上查看本教程的配套存储库

先决条件 (Prerequisites)

To follow this tutorial, you’ll need:

要遵循本教程,您需要:

步骤1 —设置新的Rails API应用程序 (Step 1 — Setting Up a New Rails API Application)

In this step, you will set up a new Rails API application and connect it to a PostgreSQL database. This will serve as the foundation for the note-taking API.

在此步骤中,您将设置一个新的Rails API应用程序并将其连接到PostgreSQL数据库。 这将作为笔记API的基础。

Rails provides commands that make building modern web applications faster for developers. These commands can perform actions that range from creating a new Rails application to generating files required for app development. For a full list of these commands and what they do, run the following command in your terminal window:

Rails提供的命令可使开发人员更快地构建现代Web应用程序。 这些命令可以执行的操作范围从创建新的Rails应用程序到生成应用程序开发所需的文件。 有关这些命令及其作用的完整列表,请在终端窗口中运行以下命令:

  • rails -h

    轨-h

This command yields an extensive list of options you can use to set the parameters of your application. One of the commands listed is the new command, which accepts an APP_PATH and creates a new Rails application at the specified path.

该命令产生了广泛的选项列表,可用于设置应用程序的参数。 列出的命令之一是new命令,该命令接受APP_PATH并在指定路径上创建一个新的Rails应用程序。

Create a new Rails application using the new generator. Run the following command in your terminal window:

使用new生成器创建一个新的Rails应用程序。 在终端窗口中运行以下命令:

  • rails new rails_graphql -d=postgresql -T --api

    rails新rails_graphql -d = postgresql -T --api

This creates a new Rails application in a directory named rails_graphql and installs the required dependencies. Let’s go over the flags associated with the new command:

这将在名为rails_graphql的目录中创建一个新的Rails应用程序,并安装所需的依赖项。 让我们看一下与new命令关联的标志:

  • The -d flag pre-configures the application with the specified database.

    -d标志使用指定的数据库预配置应用程序。

  • The -T flag instructs Rails to not generate test files since you won’t be writing tests in this tutorial. You can also use this flag if you plan to use a different testing framework other than the one provided by Rails.

    -T标志指示Rails不生成测试文件,因为在本教程中您不会编写测试。 如果您打算使用Rails提供的测试框架以外的其他测试框架,则也可以使用此标志。

  • The --api flag configures a Rails application with only the files required for building an API with Rails. It skips configuring settings needed for browser applications.

    --api标志仅使用使用Rails构建API所需的文件来配置Rails应用程序。 它跳过配置浏览器应用程序所需的设置。

Once the command is done running, switch to the newly created rails_graphql directory, which is the application’s root directory:

命令运行完成后,切换到新创建的rails_graphql目录,该目录是应用程序的根目录:

  • cd rails_graphql

    cd rails_graphql

Now that you have successfully set up a new Rails API application, you have to connect it to a database before you can run the app. Rails provides a database.yml file found in config/database.yml, which contains configurations for connecting your app to a different database for different development environments. Rails specifies a database name for different development environments by appending an underscore (_) followed by the environment name to your app’s name. You can always change any environment database name to whatever you choose.

既然您已经成功设置了新的Rails API应用程序,则必须将其连接到数据库,然后才能运行该应用程序。 Rails提供了在config/database.yml找到的database.yml文件,其中包含用于将您的应用程序连接到不同开发环境的不同数据库的配置。 Rails通过在应用程序名称后附加下划线( _ )和环境名称,为不同的开发环境指定数据库名称。 您始终可以将任何环境数据库名称更改为您选择的任何名称。

Note: You can alter config/database.yml to choose the PostgreSQL role you would like Rails to use to create your database. If you created a role that is secured by a password, follow the instructions in Step 4 of How To Use PostgreSQL with Your Ruby on Rails Application on Ubuntu 18.04 or How To Use PostgreSQL with Your Ruby on Rails Application on macOS to configure your role.

注意:您可以更改config/database.yml以选择希望Rails用于创建数据库的PostgreSQL角色。 如果您创建的角色受密码保护,请按照Ubuntu 18.04上 如何将PostgreSQL与Ruby on Rails应用程序结合使用在macOS上 如何将PostgreSQL与Ruby on Rails应用程序结合使用中的步骤4中的说明来配置您的角色。

Rails includes commands for creating and working with databases. With your database credentials in place, run the following command in your terminal window to create your databases:

Rails包含用于创建和使用数据库的命令。 有了数据库凭据之后,在终端窗口中运行以下命令来创建数据库:

  • rails db:create

    rails db:create

The db:create command creates a development and test database based on the information provided in the config/database.yml file. Running the command yields the following output:

db:create命令根据config/database.yml文件中提供的信息创建developmenttest数据库。 运行命令将产生以下输出:


   
   
Output
Created database 'rails_graphql_development' Created database 'rails_graphql_test'

With your application now successfully connected to a database, you can test the application to ensure it works. Start your server with the following command if you are working locally:

现在,您的应用程序已成功连接到数据库,您可以测试该应用程序以确保其正常运行。 如果您在本地工作,请使用以下命令启动服务器:

  • bundle exec rails server

    捆绑执行Rails服务器

If you are working on a development server, you can start your application by specifying the IP address the server should bind to:

如果在开发服务器上工作,则可以通过指定服务器应绑定到的IP地址来启动应用程序:

  • bundle exec rails server --binding=your_server_ip

    捆绑exec rails服务器--binding = your_server_ip

Note: The server listens on port 3000. If you’re working on a development server, ensure that you have opened port 3000 in your firewall to allow connections.

注意 :服务器在端口3000上侦听。 如果在开发服务器上工作,请确保已在防火墙中打开端口3000以允许连接。

The rails server command launches Puma, a web server for Ruby distributed with Rails. The --binding=your_server_ip command binds the server to any IP you provide.

rails server命令启动Puma ,这是一个与Rails一起分发的Ruby Web服务器。 --binding= your_server_ip命令将服务器绑定到您提供的任何IP。

Once you run this command, your command prompt will be replaced with the following output:

运行此命令后,命令提示符将替换为以下输出:


   
   
Output
=> Booting Puma => Rails 6.0.2.1 application starting in development => Run `rails server --help` for more startup options Puma starting in single mode... * Version 4.3.1 (ruby 2.6.3-p62), codename: Mysterious Traveller * Min threads: 5, max threads: 5 * Environment: development * Listening on tcp://127.0.0.1:3000 * Listening on tcp://[::1]:3000 Use Ctrl-C to stop

To run your application, navigate to localhost:3000 or http://your_server_ip:3000 in your browser. You’ll see the Rails default welcome page:

要运行您的应用程序,请在浏览器中导航到localhost:3000http:// your_server_ip :3000 。 您将看到Rails的默认欢迎页面:

The welcome page means you have properly set up your Rails application.

欢迎页面表示您已正确设置Rails应用程序。

To stop the server, press CTRL+C in the terminal window where the server is running.

要停止服务器,请在运行服务器的终端窗口中按CTRL+C

You have successfully set up a Rails API application for a note-taking API. In the next step, you will set up your Rails API application to receive and execute GraphQL queries.

您已经成功为记笔记API设置了Rails API应用程序。 在下一步中,您将设置Rails API应用程序以接收和执行GraphQL查询。

第2步-设置Rails的GraphQL (Step 2 — Setting Up GraphQL for Rails)

In this step, you will configure your Rails API application to work with GraphQL. You will install and set up the necessary gems required for GraphQL development in Rails.

在此步骤中,您将配置Rails API应用程序以与GraphQL一起使用。 您将在Rails中安装并设置GraphQL开发所需的必要gem。

As previously mentioned, GraphQL is language agnostic and is implemented in many programming languages. The graphql-ruby gem is the Ruby implementation for GraphQL. GraphQL also provides an interactive in-browser IDE known as GraphiQL for running GraphQL queries. The graphiql-rails gem helps you add GraphiQL to your development environment.

如前所述,GraphQL与语言无关,并以许多编程语言实现。 graphql-ruby gem是GraphQL的Ruby实现。 GraphQL还提供了一个名为GraphiQL的交互式浏览器内置 IDE,用于运行GraphQL查询。 graphiql-rails gem可帮助您将GraphiQL添加到您的开发环境中。

To install these dependencies, open the project’s Gemfile for editing, using nano or your favorite text editor:

要安装这些依赖项,请使用nano或您喜欢的文本编辑器打开项目的Gemfile进行编辑:

  • nano Gemfile

    纳米宝石文件

Add the graphql and graphiql-rails gems to your Gemfile. You can add the graphiql gem anywhere, but the graphiql-rails gem should be added under the development dependencies:

graphqlgraphiql-rails gem添加到您的Gemfile中。 您可以在任何地方添加graphiql gem,但是应该在开发依赖项下添加graphiql-rails gem:

~/rails_graphql/Gemfile
〜/ rails_graphql / Gemfile
...
group :development do
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
  gem 'graphiql-rails'
end

gem 'graphql', '1.9.18'
...

Save and close the file when you are done adding the gems.

完成添加宝石后,保存并关闭文件。

In your terminal window, use the following command to install the gems:

在终端窗口中,使用以下命令来安装gem:

  • bundle install

    捆绑安装

The output shows that the gems are installed.

输出显示宝石已安装。

The graphql gem provides generators to create various files. To view the available generators, run the following command in your terminal window:

graphql gem提供了用于创建各种文件的生成器。 要查看可用的生成器,请在终端窗口中运行以下命令:

  • rails generate

    轨道生成

The generators prefixed with graphql: are the ones associated with the graphql gem.

带有graphql:前缀的生成器是与graphql gem关联的graphql

You will use the graphql:install command to add graphql-ruby boilerplate code to the application and mount GraphiQL in your development environment. The boilerplate code will include all the files and directory needed for the graphql-ruby gem to work with Rails.

您将使用graphql:install命令将graphql-ruby样板代码添加到应用程序,并在您的开发环境中安装GraphiQL。 样板代码将包括graphql-ruby gem与Rails一起使用所需的所有文件和目录。

In your terminal window, run the following commands:

在终端窗口中,运行以下命令:

  • rails g graphql:install

    rails g graphql:安装

This command generates several files, including a graphql_controller.rb file located at app/controllers/graphql_controller.rb and a graphql directory at app/graphql which contains files required to get started with GraphQL in Rails. It also adds a /graphql HTTP POST route in the routes file located at config/routes.rb. This route is mapped to the app/controllers/graphql_controller.rb#execute method which handles all queries to the GraphQL server.

此命令生成多个文件,其中包括graphql_controller.rb位于文件app/controllers/graphql_controller.rbgraphql在目录app/graphql其中包含所需的文件,开始使用GraphQL Rails中。 它还在位于config/routes.rb的路由文件中添加了/graphql HTTP POST路由。 该路由映射到app/controllers/graphql_controller.rb#execute方法,该方法处理对GraphQL服务器的所有查询。

Before you can test the GraphQL endpoint, you need to mount the GraphiQL engine to the routes file so you can access the GraphiQL in-browser IDE. To do this open the routes file located at config/routes.rb:

在测试GraphQL端点之前,您需要将GraphiQL引擎安装到路由文件,以便可以访问GraphiQL浏览器内置IDE。 为此,请打开位于config/routes.rb的路由文件:

  • nano ~/rails_graphql/config/routes.rb

    纳米〜/ rails_graphql / config / routes.rb

Add the following code to the file to mount the GraphiQL engine in the development environment:

将以下代码添加到文件中以在开发环境中挂载GraphiQL引擎:

~/rails_graphql/config/routes.rb
〜/ rails_graphql / config / routes.rb
Rails.application.routes.draw do
  if Rails.env.development?
    mount GraphiQL::Rails::Engine, at: "/graphiql", graphql_path: "graphql#execute"
  end
  post "/graphql", to: "graphql#execute"
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end

This mounts the GraphiQL engine to the /graphiql path and directs all queries to the graphql#execute method.

这会将GraphiQL引擎安装到/graphiql路径,并将所有查询定向到graphql#execute方法。

Since this is an API application created with the --api flag, it does not expect to render any page in the browser. To make the GraphiQL editor show up in the browser, you need to make a couple of small changes to your application’s configuration.

由于这是使用--api标志创建的API应用程序,因此它不会在浏览器中呈现任何页面。 为了使GraphiQL编辑器显示在浏览器中,您需要对应用程序的配置进行一些小的更改。

First, open the application.rb file located at config/application.rb:

首先,打开位于config/application.rbapplication.rb文件:

  • nano ~/rails_graphql/config/application.rb

    纳米〜/ rails_graphql / config / application.rb

Next, uncomment the require "sprockets/railtie" line:

接下来,取消注释require "sprockets/railtie"行:

~/rails_graphql/config/application.rb
〜/ rails_graphql / config / application.rb
require_relative 'boot'

require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_mailbox/engine"
require "action_text/engine"
require "action_view/railtie"
require "action_cable/engine"
require "sprockets/railtie"
# require "rails/test_unit/railtie"

...

Save and close the file after uncommenting the line.

取消注释该行后,保存并关闭文件。

Now create a config directory at app/assets:

现在在app/assets创建一个config目录:

  • mkdir -p app/assets/config

    mkdir -p应用程序/资产/配置

Next, create a manifest.js file in the newly created config directory. The manifest.js file specifies additional assets to be compiled and made available to the browser:

接下来,在新创建的config目录中创建manifest.js文件。 manifest.js文件指定了其他要编译并可供浏览器使用的资产:

  • nano app/assets/config/manifest.js

    纳米应用程序/资产/配置/ manifest.js

Add the following code to the file which tells Rails to precompile the graphiql/rails/application.css and graphiql/rails/application.js files so Rails can serve them to your browser:

将以下代码添加到该文件中,该文件告诉Rails预编译graphiql/rails/application.cssgraphiql/rails/application.js文件,以便Rails可以将它们提供给您的浏览器:

~/rails_graphql/app/assets/config/manifest.js
〜/ rails_graphql / app / assets / config / manifest.js
//= link graphiql/rails/application.css
//= link graphiql/rails/application.js

Save and close the file.

保存并关闭文件。

With that done, you can test your GraphQL endpoint. Restart your development server, and in your browser, navigate to localhost:3000/graphiql or http://your_server_ip:3000/graphiql. The GraphiQL query editor displays in your browser:

完成后,您可以测试GraphQL端点。 重新启动开发服务器,然后在浏览器中导航到localhost:3000/graphiqlhttp:// your_server_ip :3000/graphiql 。 GraphiQL查询编辑器显示在浏览器中:

The left side of the GraphiQL IDE accepts GraphQL queries and the right side displays results of the run query. The GraphiQL query editor also has a syntax highlighter and a typeahead hinter powered by your GraphQL Schema. Together, these help you make a valid query.

GraphiQL IDE的左侧接受GraphQL查询,而右侧则显示运行查询的结果。 GraphiQL查询编辑器还具有由GraphQL Schema支持的语法突出显示和预输入提示。 这些都可以帮助您进行有效的查询。

To try a Hello World example, clear out the default text in the editor’s left pane and type in the following query:

要尝试Hello World示例,请在编辑器的左窗格中清除默认文本,然后键入以下查询:

query {
    testField
}

Click the Play icon button in the header and you’ll recieve a successful response on the screen, as shown in the following figure:

单击标题中的“ 播放”图标按钮,您将在屏幕上收到成功的响应,如下图所示:

You have successfully set up your Rails API application to work with GraphQL and tested your GraphQL endpoint to confirm it works. In the next step, you will create GraphQL types for your application.

您已经成功设置了与GraphQL一起使用的Rails API应用程序,并测试了GraphQL端点以确认它可以工作。 在下一步中,您将为您的应用程序创建GraphQL类型。

第3步-为应用程序创建类型 (Step 3 — Creating Types for the Application)

GraphQL depends on its Types and Schema to validate and respond to queries. In this step, you will create a Note model and the GraphQL types required in your note-taking API.

GraphQL取决于其类型和架构来验证和响应查询。 在此步骤中,您将创建笔记模型和笔记API中所需的GraphQL类型。

A GraphQL type consists of fields and arguments which, in turn, define the fields and arguments that can appear in any GraphQL query that operates on that type. These types make up a GraphQL Schema. GraphQL defines the following types:

GraphQL类型由fieldsarguments组成,这些fieldsarguments又定义了可以在对该类型进行操作的任何GraphQL查询中出现的字段和参数。 这些类型组成了GraphQL模式。 GraphQL定义以下类型:

  • The Query and Mutation types: These are special types that define the entry point of every GraphQL query. Every GraphQL service has a query type and may or may not have a mutation type.

    查询和突变类型:这些是特殊类型,用于定义每个GraphQL查询的入口点。 每个GraphQL服务都具有query类型,并且可能具有或不具有mutation类型。

  • Object types: These are the basic components of a GraphQL schema. These represent the objects you can fetch from a GraphQL service and the fields each object holds.

    对象类型:这些是GraphQL模式的基本组件。 这些代表您可以从GraphQL服务获取的对象以及每个对象保存的字段。
  • Scalar types: These are default types that come with GraphQL out of the box. They include Int, Float, String, Boolean, and ID.

    标量类型:这些是GraphQL随附的默认类型。 它们包括IntFloatStringBooleanID

  • Enumeration types: These are types that define a particular set of allowed values.

    枚举类型:这些类型定义了一组特定的允许值。
  • Input types: These are similar to object types, with the only difference being that they define objects that you can pass to queries as arguments.

    输入类型:这些输入类型与对象类型相似,唯一的区别是它们定义了可以作为参数传递给查询的对象。

There are other types, including Union, List, Non-Null, and Interface. You can find a list of available GraphQL types in the official GraphQL documentation.

还有其他类型,包括UnionListNon-NullInterface 。 您可以在GraphQL官方文档中找到可用GraphQL类型的列表。

For this application, you will create a Note model and a Note object and input type. The Note model will represent the database table that will store your notes while the Note object and input type will define the fields and arguments that exists on a Note object.

对于此应用程序,您将创建一个Note模型以及一个Note对象和输入类型。 Note模型将表示将存储您的注释的数据库表,而Note对象和输入类型将定义Note对象上存在的字段和参数。

First, create a Note model using the generate model subcommand provided by Rails and specify the name of the model along with its columns and data types. Run the following command in your terminal window:

首先,使用Rails提供的generate model子命令创建一个Note模型,并指定模型名称及其列和数据类型。 在终端窗口中运行以下命令:

  • rails generate model note title:string:index body:text

    Rails生成模型注释标题:字符串:索引正文:文本

This command creates a Note model with two fields: title, with the type string, and body, with the type text. The command also adds a database index on the title column. It generates these two files:

此命令创建一个具有两个字段的Note模型: title (类型为string )和body (类型为text 。 该命令还在title列上添加数据库index 。 它生成以下两个文件:

  • A note.rb file located at app/models/note.rb. This file will hold all model-related logic.

    位于app/models/note.rb note.rb文件。 该文件将包含所有与模型相关的逻辑。

  • A 20200617173228_create_notes.rb file (the number at the beginning of the file will differ, depending on the date you run the command) located at db/migrate/20200617173228_create_notes.rb. This is a migration file that holds the instruction for creating a corresponding notes table in the database.

    位于db/migrate/ 20200617173228 _create_notes.rb20200617173228 _create_notes.rb文件(文件开头的数字会有所不同,具体取决于您运行命令的日期)。 这是一个迁移文件,其中包含用于在数据库中创建相应notes表的指令。

To execute the instructions in the migration file, you’ll use the db:migrate subcommand which executes the instruction in your migration files. Run the following command in your terminal window:

要执行迁移文件中的指令,您将使用db:migrate子命令,该子命令将在迁移文件中执行指令。 在终端窗口中运行以下命令:

  • rails db:migrate

    rails db:migrate

Once the command runs successfully, you will see output similar to the following:

命令成功运行后,您将看到类似于以下内容的输出:


   
   
Output
== 20200617173228 CreateNotes: migrating ====================================== -- create_table(:notes) -> 0.0134s -- add_index(:notes, :title) -> 0.0073s == 20200617173228 CreateNotes: migrated (0.0208s) =============================

With the note model in place, next you’ll create a NoteType. A valid note object is expected to have an id, a title, and text. Run the following command in your terminal window to create a NoteType:

放置好便笺模型后,接下来将创建一个NoteType 。 有效的注释对象应具有idtitletext 。 在终端窗口中运行以下命令以创建NoteType

  • rails generate graphql:object Note id:ID! title:String! body:String!

    rails生成graphql:object注释ID:ID! 标题:字符串! 身体:细绳!

The command instructs Rails to create a GraphQL object type called Note with three fields: an id field with a type of ID, and the title and body fields, each with a String type. The exclamation point (!) appended to the field type indicates that the field should be non-nullable, meaning that the field should never return a null value. Non-nullable fields are important, as they serve as a form of validation that guarantees which fields must be present whenever GraphQL objects are queried.

该命令指示Rails创建称为GraphQL对象类型Note带有三个字段:一个id与一种类型的字段ID ,和所述titlebody字段,每一个String类型。 附加到字段类型的感叹号( ! )表示该字段不可为空,这意味着该字段永远不应返回空值。 非空字段很重要,因为它们用作一种验证形式,可确保在查询GraphQL对象时必须存在哪些字段。

Running the preceding command creates a note_type.rb file located at app/graphql/types/note_type.rb containing a Types::NoteType class with three non-nullable fields.

运行前面的命令会创建一个位于app/graphql/types/note_type.rbnote_type.rb文件,其中包含具有三个不可为空字段的Types::NoteType类。

Lastly, you will create a NoteInput type to define the arguments required to create a note. Start by creating an input directory under app/graphql/types. The input directory will house input types:

最后,您将创建一个NoteInput类型来定义创建注释所需的参数。 首先在app/graphql/types下创建一个input目录。 输入目录将包含输入类型:

  • mkdir ~/rails_graphql/app/graphql/types/input

    mkdir〜/ rails_graphql / app / graphql / types / input

Note: It’s not a requirement to create input types in the input directory; it is merely a common convention. You can decide to keep all your types under the types directory and exclude nesting the class under an Input module whenever you’re accessing it.

注意:不需要在输入目录中创建输入类型。 这只是一个常见的约定。 您可以决定将所有类型都保留在类型目录下,并在每次访问类时将其嵌套在Input模块下。

In the ~/rails_graphql/app/graphql/types/input directory, create a note_input_type.rb file:

~/rails_graphql/app/graphql/types/input目录中,创建一个note_input_type.rb文件:

  • nano ~/rails_graphql/app/graphql/types/input/note_input_type.rb

    纳米〜/ rails_graphql / app / graphql / types / input / note_input_type.rb

Add the following code to the file to define the fields for the Input type:

将以下代码添加到文件中,以定义Input类型的字段:

~/rails_graphql/app/graphql/types/input/note_input_type.rb
〜/ rails_graphql / app / graphql / types / input / note_input_type.rb
module Types
  module Input
    class NoteInputType < Types::BaseInputObject
      argument :title, String, required: true
      argument :body, String, required: true
    end
  end
end

In the note_input_type.rb file, you added a Types::Input::NoteInputType class that inherits from the Types::BaseInputObject class and accepts two required arguments; title and body, both of a string type.

note_input_type.rb文件中,添加了一个Types::Input::NoteInputType类,该类继承自Types::BaseInputObject类并接受两个必需的参数。 titlebody ,均为字符串类型。

You’ve created a model and two GraphQL types for your note-taking app. In the next step, you will create queries to fetch existing notes.

您已经为记笔记应用程序创建了一个模型和两种GraphQL类型。 在下一步中,您将创建查询以获取现有注释。

第4步-为应用程序创建查询 (Step 4 — Creating Queries for the Application)

Your GraphQL-powered API is gradually coming together. In this step you’ll create two queries; one to fetch a single note by id and another to fetch all notes. The GraphQL query type handles the fetching of data and can be likened to a GET request in REST.

您的GraphQL驱动的API逐渐融合在一起。 在这一步中,您将创建两个查询; 一个通过id提取单个便笺,另一个通过所有便笺获取。 GraphQL query类型处理数据的获取,并且可以比作REST中的GET请求。

First, you’ll create a query to fetch all notes. To start, create a queries directory to house all queries:

首先,您将创建一个查询以获取所有注释。 首先,创建一个queries目录以容纳所有查询:

  • mkdir ~/rails_graphql/app/graphql/queries

    mkdir〜/ rails_graphql / app / graphql / queries

In the app/graphql/queries directory, create a base_query.rb file from which all other query classes will inherit:

app/graphql/queries目录中,创建一个base_query.rb文件,所有其他查询类将从该文件中继承:

  • nano ~/rails_graphql/app/graphql/queries/base_query.rb

    纳米〜/ rails_graphql / app / graphql / queries / base_query.rb

Add the following code to the base_query.rb file to create a BaseQuery class that other query classes will inherit from:

将以下代码添加到base_query.rb文件中,以创建其他查询类将从其继承的BaseQuery类:

~/rails_graphql/app/graphql/queries/base_query.rb
〜/ rails_graphql / app / graphql / queries / base_query.rb
module Queries
  class BaseQuery < GraphQL::Schema::Resolver
  end
end

In the base_query.rb file, you added a Queries::BaseQuery class that inherits from the GraphQL::Schema::Resolver class. The GraphQL::Schema::Resolver class is a container that can hold logic belonging to a field. It can be attached to a field with the resolver: keyword.

base_query.rb文件中,添加了一个Queries::BaseQuery类,该类继承自GraphQL::Schema::Resolver类。 GraphQL::Schema::Resolver类是一个容器,可以容纳属于field逻辑。 可以使用resolver:关键字将其附加到field

The Queries::BaseQuery class can also contain any code you intend to reuse across multiple query classes.

Queries::BaseQuery类还可以包含您打算在多个查询类中重用的任何代码。

Next, create a fetch_notes.rb file in the queries directory. This file will hold the logic for fetching all existing notes, and will be attached to a field in the query type file:

接下来,在queries目录中创建一个fetch_notes.rb文件。 该文件将包含用于获取所有现有注释的逻辑,并将附加到查询类型文件中的field

  • nano ~/rails_graphql/app/graphql/queries/fetch_notes.rb

    纳米〜/ rails_graphql / app / graphql / queries / fetch_notes.rb

Add the following code to the file to define the return object type and resolve the requested notes:

将以下代码添加到文件中,以定义返回对象类型并解决请求的注释:

~/rails_graphql/app/graphql/queries/fetch_notes.rb
〜/ rails_graphql / app / graphql / queries / fetch_notes.rb
module Queries
  class FetchNotes < Queries::BaseQuery

    type [Types::NoteType], null: false

    def resolve
      Note.all.order(created_at: :desc)
    end
  end
end

In the fetch_notes.rb file, you created a Queries::FetchNotes class that inherits the Queries::BaseQuery previously created. The class has a return type declaration that declares that the data returned by this query should be an array of the already created NoteType.

fetch_notes.rb文件中,您创建了一个Queries::FetchNotes类,该类继承了先前创建的Queries::BaseQuery 。 该类具有返回type声明,该声明声明此查询返回的数据应为已创建的NoteType的数组。

The Queries::FetchNotes also contains a resolve method that returns an array of all existing notes sorted by their created date in descending order.

Queries::FetchNotes还包含一个resolve方法,该方法返回所有现有便笺的数组,这些便笺按其创建日期降序排列。

The FetchNotes query is ready to receive and return requests for notes, but GraphQL is still unaware of its existence, to fix that, open the GraphQL query type file located at app/graphql/types/query_type.rb:

FetchNotes查询已准备就绪,可以接收和返回对笔记的请求,但是GraphQL仍然不知道其存在,要解决此问题,请打开位于app/graphql/types/query_type.rb的GraphQL查询类型文件:

  • nano ~/rails_graphql/app/graphql/types/query_type.rb

    纳米〜/ rails_graphql / app / graphql / types / query_type.rb

The query_type.rb file is the entry point for all GraphQL query types. It holds the query fields, and their respective resolver methods. Replace the sample code in the file with the following:

query_type.rb文件是所有GraphQL query类型的入口点。 它包含查询字段及其各自的解析器方法。 用以下内容替换文件中的示例代码:

~/rails_graphql/app/graphql/types/query_type.rb
〜/ rails_graphql / app / graphql / types / query_type.rb
module Types
  class QueryType < Types::BaseObject
    # Add root-level fields here.
    # They will be entry points for queries on your schema.

    field :fetch_notes, resolver: Queries::FetchNotes
  end
end

In the query_type.rb file, you added a fetch_notes field and attached it to the Queries::FetchNotes class using a resolver:. This way whenever the fetch_notes query is called, it executes the logic in the resolve method of the Queries::FetchNotes class.

query_type.rb文件中,添加了一个fetch_notes字段,并使用resolver:将其附加到Queries::FetchNotes类。 这样,无论何时调用fetch_notes查询,它都会在Queries::FetchNotes类的resolve方法中执行逻辑。

In order to test your query, you need some data to fetch, but you currently don’t have any notes in your database. You can fix that by adding some seed data to your database. Open the seeds.rb file located at db/seeds.rb:

为了测试您的查询,您需要获取一些数据,但是当前数据库中没有任何注释。 您可以通过将一些种子数据添加到数据库中来解决此问题。 打开位于db/seeds.rbseeds.rb文件:

  • nano ~/rails_graphql/db/seeds.rb

    纳米〜/ rails_graphql / db / seeds.rb

Add the following code to the file to create five notes:

将以下代码添加到文件中以创建五个注释:

~/rails_graphql/db/seeds.rb
〜/ rails_graphql / db / seeds.rb
5.times do |i|
  Note.create(title: "Note #{i + 1}", body: 'Lorem ipsum saves lives')
end

Save and close the file after adding the code.

添加代码后,保存并关闭文件。

Open your project’s root directory in another terminal window and run the following command to run the code in the seed.rb file:

在另一个终端窗口中打开项目的根目录,然后运行以下命令以运行seed.rb文件中的代码:

  • rails db:seed

    rails db:seed

This creates 5 notes in the database.

这将在数​​据库中创建5个注释。

With data in your database, and your development server running, navigate to localhost:3000/graphiql or http://your_server_ip:3000/graphiql in your browser to open your GraphiQL IDE. In the left side of the editor, type in the following query:

在数据库中有数据且开发服务器正在运行的情况下,在浏览器中导航到localhost:3000/graphiqlhttp:// your_server_ip :3000/graphiql以打开GraphiQL IDE。 在编辑器的左侧,输入以下查询:

query {
  fetchNotes {
    id
    title
    body
  }
}

This GraphQL query declares a query operation, indicating you want to make a query request. In the query operation, you called a fetchNotes field that matches the fetch_notes query field declared in the API, and included the fields on a note that you want to be returned in your response.

此GraphQL查询声明query操作,指示您要发出查询请求。 在查询操作中,您调用了一个fetchNotes字段,该字段与API中声明的fetch_notes查询字段相匹配,并在要在响应中返回的便笺上包含了这些字段。

Click the Play icon button in the header. You’ll see a response similar to the following in the output pane:

单击标题中的“ 播放”图标按钮。 您会在输出窗格中看到类似于以下内容的响应:

{
  "data": {
    "fetchNotes": [
      {
        "id": "5",
        "title": "Note 5",
        "body": "Lorem ipsum saves lives"
      },
      {
        "id": "4",
        "title": "Note 4",
        "body": "Lorem ipsum saves lives"
      },
      {
        "id": "3",
        "title": "Note 3",
        "body": "Lorem ipsum saves lives"
      },
      {
        "id": "2",
        "title": "Note 2",
        "body": "Lorem ipsum saves lives"
      },
      {
        "id": "1",
        "title": "Note 1",
        "body": "Lorem ipsum saves lives"
      }
    ]
  }
}

The response contains an array of 5 notes that match the fields declared in the query on the left. If you remove some fields in the query on the left side of the editor and re-run the query, you get a response with only the fields you requested. That’s the power of GraphQL.

响应包含5个注释的数组,这些注释与左侧查询中声明的字段匹配。 如果您在编辑器左侧的查询中删除了某些字段,然后重新运行该查询,则只会收到您要求的字段的响应。 这就是GraphQL的力量。

Next, you’ll create another query to fetch notes by id. This query will be similar to the fetch_notes query, only that it’ll accept an id argument. Go ahead and create a fetch_note.rb file in the queries directory:

接下来,您将创建另一个查询以按id提取注释。 该查询将类似于fetch_notes查询,只是它将接受id参数。 继续,在查询目录中创建一个fetch_note.rb文件:

  • nano ~/rails_graphql/app/graphql/queries/fetch_note.rb

    纳米〜/ rails_graphql / app / graphql / queries / fetch_note.rb

Add the following code to the file to find and return a note with the provided id:

将以下代码添加到文件中,以查找并返回具有提供的id的注释:

~/rails_graphql/app/graphql/queries/fetch_note.rb
〜/ rails_graphql / app / graphql / queries / fetch_note.rb
module Queries
  class FetchNote < Queries::BaseQuery
    type Types::NoteType, null: false
    argument :id, ID, required: true

    def resolve(id:)
      Note.find(id)
    rescue ActiveRecord::RecordNotFound => _e
      GraphQL::ExecutionError.new('Note does not exist.')
    rescue ActiveRecord::RecordInvalid => e
      GraphQL::ExecutionError.new("Invalid attributes for #{e.record.class}:"\
        " #{e.record.errors.full_messages.join(', ')}")
    end
  end
end

This defines a Queries::FetchNote class that inherits from the Queries::BaseQuery class. This class not only returns a single item that must be of a NoteType, it also accepts an id argument with an ID type. The resolve method receives the provided id argument, then finds and returns a note with the provided id. If no note exists or an error occurs, it is rescued and returned as a GraphQL::ExecutionError.

这定义了一个Queries::FetchNote类,该类继承自Queries::BaseQuery类。 此类不仅返回必须为NoteType的单个项目,而且还接受具有ID类型的id参数。 resolve方法接收提供的id参数,然后查找并返回带有提供的id的注释。 如果不存在任何注释或发生错误,则将其恢复并作为GraphQL::ExecutionError返回。

Next, you will attach the Queries::FetchNote class to a query field in the query type file. Open the query_type.rb file in your editor:

接下来,将Queries::FetchNote类附加到查询类型文件中的查询字段。 在编辑器中打开query_type.rb文件:

  • nano ~/rails_graphql/app/graphql/types/query_type.rb

    纳米〜/ rails_graphql / app / graphql / types / query_type.rb

Add the following code to the file which defines a resolver for fetch_notes:

将以下代码添加到为fetch_notes定义解析器的文件中:

~/rails_graphql/app/graphql/types/query_type.rb
〜/ rails_graphql / app / graphql / types / query_type.rb
module Types
  class QueryType < Types::BaseObject
    # Add root-level fields here.
    # They will be entry points for queries on your schema.

    field :fetch_notes, resolver: Queries::FetchNotes
    field :fetch_note, resolver: Queries::FetchNote
  end
end

To test your new query, ensure your server is running and navigate to localhost:3000/graphiql or http://your_server_ip:3000/graphiql in your browser to open your GraphiQL IDE. In the left side of the editor, type in the following query:

要测试新查询,请确保服务器正在运行,并在浏览器中导航到localhost:3000/graphiqlhttp:// your_server_ip :3000/graphiql以打开GraphiQL IDE。 在编辑器的左侧,输入以下查询:

query {
  fetchNote(id: 1) {
    id
    title
    body
  }
}

This query operation requests a fetchNote field, which corresponds to the fetch_note query field, and is passed an id argument. It specifies that we want three fields to be returned in the response.

此查询操作请求一个fetchNote字段,该字段与fetch_note查询字段相对应,并传递了id参数。 它指定我们希望在响应中返回三个字段。

Run the query by clicking the Play icon button in the header. You will get a response like the following in the output pane:

通过单击标题中的“ 播放”图标按钮运行查询。 在输出窗格中,您将收到类似以下的响应:

{
  "data": {
    "fetchNote": {
      "id": "1",
      "title": "Note 1",
      "body": "Lorem ipsum saves lives"
    }
  }
}

The response contains a single note that matches the requested id with fields matching the ones in the request.

响应中包含一条注释,该注释将请求的id与匹配请求中的id的字段进行匹配。

In this step, you created GraphQL queries to fetch notes from your API. Next you’ll write mutations to create notes.

在此步骤中,您创建了GraphQL查询以从您的API中获取注释。 接下来,您将编写变体来创建笔记。

步骤5 —创建GraphQL突变以修改注释 (Step 5 — Creating GraphQL Mutations to Modify Notes)

In addition to queries, GraphQL also defines a mutation type for operations that modify server-side data. Just as REST provides POST, PUT, PATCH, and DELETE requests for creating, updating and deleting resources, GraphQL’s mutation type defines a convention for operations that cause writes on the server-side. In this step, you’ll create a mutation for adding new notes.

除了查询之外,GraphQL还为修改服务器端数据的操作定义了一种mutation类型。 就像REST提供POSTPUTPATCHDELETE请求以创建,更新和删除资源一样,GraphQL的mutation类型定义了导致在服务器端进行写操作的约定。 在此步骤中,您将创建一个变异以添加新的笔记。

graphQL-ruby includes two classes for writing mutations. They are:

graphQL-ruby包括两个用于编写突变的类。 他们是:

  • GraphQL::Schema::Mutation: This is the generic base class for writing mutations. If you don’t want an input argument required in your mutations, you should use this class.

    GraphQL :: Schema :: Mutation :这是用于编写突变的通用基类。 如果您不希望突变中需要input参数,则应使用此类。

  • GraphQL::Schema::RelayClassicMutation: This is a base class with some conventions; an argument called clientMutationId that is always inserted to the response, and mutations that accepts one argument called input. This class is used by default when you use the install generator to add boilerplate GraphQL files to your project.

    GraphQL :: Schema :: RelayClassicMutation :这是具有一些约定的基类; 始终插入响应中的名为clientMutationId的参数,以及接受一个称为input参数的变体。 当您使用install generator将样板GraphQL文件添加到项目时,默认情况下使用此类。

Create an add_note.rb file in the mutations directory located at app/graphql/mutations:

在位于app/graphql/mutationsmutations目录中创建一个add_note.rb文件:

  • nano ~/rails_graphql/app/graphql/mutations/add_note.rb

    纳米〜/ rails_graphql / app / graphql / mutations / add_note.rb

Add the following code to the file to define the mutation for adding new notes:

将以下代码添加到文件中,以定义用于添加新注释的突变:

~/rails_graphql/app/graphql/mutations/add_note.rb
〜/ rails_graphql / app / graphql / mutations / add_note.rb
module Mutations
  class AddNote < Mutations::BaseMutation
    argument :params, Types::Input::NoteInputType, required: true

    field :note, Types::NoteType, null: false

    def resolve(params:)
      note_params = Hash params

      begin
        note = Note.create!(note_params)

        { note: note }
      rescue ActiveRecord::RecordInvalid => e
        GraphQL::ExecutionError.new("Invalid attributes for #{e.record.class}:"\
          " #{e.record.errors.full_messages.join(', ')}")
      end
    end
  end
end

This defines a Mutations::AddNote class that inherits from the Mutations::BaseMutation class, which is one of the classes created when you ran the install generator while installing the GraphQL-Ruby gem. The Mutations::AddNote class receives an argument with the name params and a type of NoteInputType, which you created in Step 3. It also returns a field called note that must be a non-null NoteType type.

这定义了一个Mutations::AddNote类,该类继承自Mutations::BaseMutation类,该类是在安装GraphQL-Ruby gem时运行install generator时创建的类之一。 Mutations::AddNote类接收一个名称为params且类型为NoteInputTypeargument ,该params是您在步骤3中创建的。它还返回一个称为notefield ,该field必须为非null的NoteType类型。

The resolve method of the class receives the params and converts it to a hash which it uses to create and return a new hash containing the new note. If there’s an error while creating the note, the error is rescued and returned as a GraphQL::ExecutionError.

该类的resolve方法接收params ,并将其转换为哈希,用于创建并返回包含新笔记的新哈希。 如果在创建便笺时出现错误,则可以挽救该错误并将其作为GraphQL::ExecutionError返回。

Note: The resolve method in a mutation must return a hash whose symbol matches the field names.

注意:突变中的resolve方法必须返回其符号与field名称匹配的哈希。

Like with queries, the Mutations::AddNote mutation has to be attached to a mutation field using the mutation: keyword.

与查询类似,必须使用mutation:关键字将Mutations::AddNote突变附加到突变字段。

Open the mutation type file located at app/graphql/types/mutation_type.rb in your editor:

在编辑器中打开位于app/graphql/types/mutation_type.rb的突变类型文件:

  • nano ~/rails_graphql/app/graphql/types/mutation_type.rb

    纳米〜/ rails_graphql / app / graphql / types / mutation_type.rb

Replace the code in the file with the following code, which adds a field for the add_note with its corresponding mutation class:

用以下代码替换文件中的代码,该代码将为add_note添加一个字段及其相应的突变类:

~/rails_graphql/app/graphql/types/mutation_type.rb
〜/ rails_graphql / app / graphql / types / mutation_type.rb
module Types
  class MutationType < Types::BaseObject
    field :add_note, mutation: Mutations::AddNote
  end
end

In this code, you added an add_note field to the mutation type file and attached it to the Mutations::AddNote class using the mutation: keyword. When the add_note mutation is called, it runs the code in the resolve method of the Mutations::AddNote class.

在此代码中,您向变异类型文件添加了一个add_note字段,并使用mutation:关键字将其附加到Mutations::AddNote类。 调用add_note突变时,它将在Mutations::AddNote类的resolve方法中运行代码。

To test your new mutation, navigate to localhost:3000/graphiql or http://your_server_ip:3000/graphiql in your browser to open your GraphiQL IDE. In the left side of the editor, type in the following query:

要测试您的新突变,请在浏览器中导航到localhost:3000/graphiqlhttp:// your_server_ip :3000/graphiql以打开GraphiQL IDE。 在编辑器的左侧,输入以下查询:

mutation {
  addNote(input: { params: { title: "GraphQL notes", body: "A long body of text about GraphQL"  }}) {
    note {
      id
      title
      body
    }
  }
}

This declares a mutation operation with an addNote field that accepts a single input argument, which in turn accepts a param object with keys that match the NoteInputType. The mutation operation also includes a note field that matches the note field returned by the Mutations::AddNote class.

这声明了一个带有addNote字段的变异操作,该字段接受一个input参数,该input参数又接受一个其键与NoteInputType匹配的param对象。 突变操作还包括一个与Mutations::AddNote类返回的note字段匹配的note字段。

Run the mutation in GraphiQL and you’ll see the following results in the output pane:

在GraphiQL中运行该突变,您将在输出窗格中看到以下结果:

{
  "data": {
    "addNote": {
      "note": {
        "id": "6",
        "title": "GraphQL notes",
        "body": "A long body of text about GraphQL"
      }
    }
  }
}

The response returned is the newly created note with the fields requested in the mutation request.

返回的响应是新创建的注释,其中包含突变请求中要求的字段。

With your add_note mutation now working, your API can fetch and create notes using GraphQL queries and mutations.

在您的add_note变异现在可以正常工作的情况下,您的API可以使用GraphQL查询和变异来获取和创建笔记。

结论 (Conclusion)

In this tutorial, you created a note-taking API application with Ruby on Rails using PostgreSQL as your database and GraphQL as your API query language. You can learn more about GraphQL on its official website. The GraphQL-Ruby gem website also contains some guides to help you work with GraphQL in Rails.

在本教程中,您使用Ruby on Rails创建了一个笔记API应用程序,使用PostgreSQL作为数据库,并使用GraphQL作为API查询语言。 您可以在GraphQL的官方网站上了解更多信息。 GraphQL-Ruby gem网站还包含一些指南,以帮助您在Rails中使用GraphQL。

翻译自: https://www.digitalocean.com/community/tutorials/how-to-set-up-a-ruby-on-rails-graphql-api

ruby on rails

 类似资料: