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计划的一部分接受捐赠。
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上查看本教程的配套存储库 。
To follow this tutorial, you’ll need:
要遵循本教程,您需要:
The Ruby programming language and the Ruby on Rails framework installed on your development machine. This tutorial was tested on version 2.6.3 of Ruby and version 6.0.2.1 of Rails, so make sure to specify these versions during the installation process. Follow one of these tutorials to install Ruby and Rails:
开发机器上安装的Ruby编程语言和Ruby on Rails框架。 本教程已在Ruby 2.6.3版和Rails 6.0.2.1版上进行了测试,因此请确保在安装过程中指定这些版本。 按照以下教程之一安装Ruby和Rails:
How To Use PostgreSQL with Your Ruby on Rails Application on Ubuntu 18.04
How To Use PostgreSQL with Your Ruby on Rails Application on macOS.
To develop this application on a different distribution of Linux or on another operating system, visit the official PostgreSQL downloads page. For more information on how to use PostgreSQL, visit How To Install and Use PostgreSQL.
要在其他Linux发行版或其他操作系统上开发此应用程序,请访问官方PostgreSQL下载页面 。 有关如何使用PostgreSQL更多信息,请访问如何安装和使用PostgreSQL 。
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应用程序到生成应用程序开发所需的文件。 有关这些命令及其作用的完整列表,请在终端窗口中运行以下命令:
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包含用于创建和使用数据库的命令。 有了数据库凭据之后,在终端窗口中运行以下命令来创建数据库:
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
文件中提供的信息创建development
和test
数据库。 运行命令将产生以下输出:
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:
现在,您的应用程序已成功连接到数据库,您可以测试该应用程序以确保其正常运行。 如果您在本地工作,请使用以下命令启动服务器:
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:3000
或http:// 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查询。
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
进行编辑:
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:
将graphql
和graphiql-rails
gem添加到您的Gemfile中。 您可以在任何地方添加graphiql
gem,但是应该在开发依赖项下添加graphiql-rails
gem:
...
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:
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提供了用于创建各种文件的生成器。 要查看可用的生成器,请在终端窗口中运行以下命令:
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:
在终端窗口中,运行以下命令:
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.rb
和graphql
在目录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
的路由文件:
Add the following code to the file to mount the GraphiQL engine in the development environment:
将以下代码添加到文件中以在开发环境中挂载GraphiQL引擎:
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.rb
的application.rb
文件:
Next, uncomment the require "sprockets/railtie"
line:
接下来,取消注释require "sprockets/railtie"
行:
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
目录:
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
文件指定了其他要编译并可供浏览器使用的资产:
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.css
和graphiql/rails/application.js
文件,以便Rails可以将它们提供给您的浏览器:
//= 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/graphiql
或http:// 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类型。
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类型由fields
和arguments
组成,这些fields
和arguments
又定义了可以在对该类型进行操作的任何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
类型。
Scalar types: These are default types that come with GraphQL out of the box. They include Int
, Float
, String
, Boolean
, and ID
.
标量类型:这些是GraphQL随附的默认类型。 它们包括Int
, Float
, String
, Boolean
和ID
。
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.
还有其他类型,包括Union
, List
, Non-Null
和Interface
。 您可以在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
模型,并指定模型名称及其列和数据类型。 在终端窗口中运行以下命令:
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.rb
的20200617173228 _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
子命令,该子命令将在迁移文件中执行指令。 在终端窗口中运行以下命令:
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
。 有效的注释对象应具有id
, title
和text
。 在终端窗口中运行以下命令以创建NoteType
:
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
,和所述title
和body
字段,每一个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.rb
的note_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
目录。 输入目录将包含输入类型:
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
文件:
Add the following code to the file to define the fields for the Input
type:
将以下代码添加到文件中,以定义Input
类型的字段:
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
类并接受两个必需的参数。 title
和body
,均为字符串类型。
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类型。 在下一步中,您将创建查询以获取现有注释。
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
目录以容纳所有查询:
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
文件,所有其他查询类将从该文件中继承:
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
类:
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
:
Add the following code to the file to define the return object type and resolve the requested notes:
将以下代码添加到文件中,以定义返回对象类型并解决请求的注释:
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查询类型文件:
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
类型的入口点。 它包含查询字段及其各自的解析器方法。 用以下内容替换文件中的示例代码:
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.rb
的seeds.rb
文件:
Add the following code to the file to create five notes:
将以下代码添加到文件中以创建五个注释:
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
文件中的代码:
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/graphiql
或http:// 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
文件:
Add the following code to the file to find and return a note with the provided id
:
将以下代码添加到文件中,以查找并返回具有提供的id
的注释:
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
文件:
Add the following code to the file which defines a resolver for fetch_notes
:
将以下代码添加到为fetch_notes
定义解析器的文件中:
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/graphiql
或http:// 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中获取注释。 接下来,您将编写变体来创建笔记。
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提供POST
, PUT
, PATCH
和DELETE
请求以创建,更新和删除资源一样,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/mutations
的mutations
目录中创建一个add_note.rb
文件:
Add the following code to the file to define the mutation for adding new notes:
将以下代码添加到文件中,以定义用于添加新注释的突变:
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
且类型为NoteInputType
的argument
,该params
是您在步骤3中创建的。它还返回一个称为note
的field
,该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
的突变类型文件:
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
添加一个字段及其相应的突变类:
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/graphiql
或http:// 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查询和变异来获取和创建笔记。
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