GraphQL是由Facebook开发并开源的数据查询语言。它是一个可用于构建强大API的工具。灵丹妙药,但它绝对可以帮助你解决一些问题,例如在单个请求中获取许多的资源。它不会受到过度获取或数据不足的影响,并且与REST API相反,GraphQL是强类型的,而且没有版本化。
在本文中,我将会向你展示如何在Ruby on Rails项目中如何使用PostgreSQL和设置GraphQL。
建立
我假设在你的计算机上已经安装了最新版本的Ruby。如果没有,你可以通过asdf或rvm安装。并且已经在你的应用程序创建了一个gemset。你还需要的是安装并运行PostgreSQL。
通常,创建一个新的Rails应用程序,你必须先安装bundler
gem install bundler
然后使用此命令安装最新的rails(可能需要一段时间)
bundle install rails
最后,使用以下命令生成一个新的rails项目,并指定这个项目所使用的数据库,我们这里选择postgresql
rails new graphql_test --database=postgresql
创建一个数据库,注意创建数据库前,请先设置你的database.yml文件
添加GraphQL
我们使用graphql-ruby gem包,所以你必须添加到你的Gemfile中。
gem 'graphql'
安装依赖
bundle install
然后使用以下命令进行安装
rails generate graphql:install
以下是你将要做的一些事:
在config/routes.rb中添加一行路由
post "/graphql", to: "graphql#execute"
在GraphQL API中,我们定义了一个可用于检索或更改数据的端口。这个端口将在路径/graphql中可用。但记住,你必须使用POST方法来访问。
创建graphQL控制器 app / controllers / graphql_controller.rb文件,它将处理execute方法中的所有查询:
class GraphqlController < ApplicationControllerdef executevariables = ensure_hash(params[:variables])query = params[:query]operation_name = params[:operationName]context = { # Query context goes here, for example: # current_user: current_user,}result = GraphqlTestSchema.execute(query, variables: variables,context: context,operation_name: operation_name)render json: resultrescue => eraise e unless Rails.env.development?handle_error_in_development eend # private methods are also here but are not relevant for nowend
需要注意的是我们收集GraphqlTestSchema.execute方法的参数的方式。
添加了很多base类型:
base_enum, base_input_object, base_interface, base_object, base_scalar, base_union, mutation_type, query_type
我们将使用它们来构建mutations,查询,接口和其他类型。
将gem“graphiql-rails”,group :: development添加到你的Gemfile中,该Gemfile安装了在开发期间使用的GraphiQL IDE。最后记住bundle install。查看routes.rb文件,会生成以下代码行:
if Rails.env.development? mount GraphiQL::Rails::Engine, at: "/graphiql", graphql_path: "/graphql"end
这样就能够使用/ graphiql路径在本地进行测试。
添加app / graphql / store_manager_schema.rb,它将成为整个应用程序的入口
class GraphqlTestSchema < GraphQL::Schema mutation(Types::MutationType) query(Types::QueryType)end
创建模型和数据
rails generate model Author first_name:string last_name:string date_of_birth:date --no-test-frameworkrails generate model Book title:string author:references publication_date:integer genre:string --no-test-framework
它们将生成我们可以使用rake db:migrate运行的迁移。他们还将生成模型。我们唯一要做的就是添加
has_many :books
到app / models / author.rb中
编辑db / seeds.rb:
stephen = Author.create(first_name: 'Stephen', last_name: 'King', date_of_birth: Date.parse('1947-09-21'))lee = Author.create(first_name: 'Lee', last_name: 'Child', date_of_birth: Date.parse('1954-10-29'))
Book.create(title: 'The Shining', author: stephen, publication_date: 1977, genre: 'Horror')Book.create(title: 'Carrie', author: stephen, publication_date: 1974, genre: 'Horror')Book.create(title: 'It', author: stephen, publication_date: 1986, genre: 'Horror')Book.create(title: 'Green mile', author: stephen, publication_date: 1996, genre: 'Mystery')Book.create(title: 'Killing Floor', author: lee, publication_date: 1997, genre: 'Thriller')Book.create(title: 'Die Trying', author: lee, publication_date: 1998, genre: 'Thriller')
使用rake db:seed运行seeds
生成类型
正如我之前提到的,GraphQL是强类型的,这意味着如果我们想要查询Author和Book,我们必须为它们定义类型。
app/graphql/types/author_type.rb
module Typesclass AuthorType < Types::BaseObject field :books, [Types::BookType], null: true field :id, ID, null: false field :date_of_birth, String, null: false field :first_name, String, null: false field :last_name, String, null: falseend
app/graphql/types/book_type.rb
module Typesclass BookType < Types::BaseObject field :author, Types::AuthorType, null: false field :genre, Enums::Genre, null: false
field :id, ID, null: false
field :publication_date, Integer, null: false field :title, String, null: falseendend
我们有一个约定,我们在顶部添加complex类型,然后是ID,最后是simple类型,如Integer,String等。正如你看到的,我们正在使用类型的枚举。 我们在单独的目录app / graphql / types / enums / genre.rb中定义枚举。
阅读全文
https://mp.weixin.qq.com/s?__biz=MzU2MTY0NDY4Ng==&tempkey=MTAwM19GT3lWRnA4U1grckJsbTN2MlVaV2pnQzdBbVNDNktGUlBuMnF6N19ZWTVNOVpsTkQydWJRdlJNWm4wSmZxUkNCLWdXcXhmdTh3a05yYUJaZE5iR1p2b3J5di0wckpUQTRvOEp4dzhGVi1XSWdBbmp1aTlCQmJTS28yaW1rVmFxUnBZSW9HVUM3V0xXRER0TVdINmVwaWRCQ0VfeTE1dno1R3NPWEtnfn4%3D&chksm=7c74d4cf4b035dd95dae327f8664e475d82e88c91d54dc56c75ff6c23c72b9164799f6c0772f#rd
微信公众号: