spec/support/star_wars/schema.rb in graphql-1.8.18 vs spec/support/star_wars/schema.rb in graphql-1.9.0.pre1
- old
+ new
@@ -13,19 +13,20 @@
class BaseType < GraphQL::Schema::Object
graphql_name "Base"
implements GraphQL::Relay::Node.interface
global_id_field :id
- field :name, String, null: false, resolve: ->(obj, args, ctx) {
+ field :name, String, null: false
+ def name
LazyWrapper.new {
- if obj.id.nil?
+ if object.id.nil?
raise GraphQL::ExecutionError, "Boom!"
else
- obj.name
+ object.name
end
}
- }
+ end
field :planet, String, null: true
end
class BaseEdge < GraphQL::Types::Relay::BaseEdge
@@ -84,22 +85,21 @@
def field_name
object.field.name
end
end
- # Example of GraphQL::Function used with the connection helper:
- class ShipsWithMaxPageSize < GraphQL::Function
- argument :nameIncludes, GraphQL::STRING_TYPE
- def call(obj, args, ctx)
- all_ships = obj.ships.map { |ship_id| StarWars::DATA["Ship"][ship_id] }
- if args[:nameIncludes]
- all_ships = all_ships.select { |ship| ship.name.include?(args[:nameIncludes])}
+ class ShipsWithMaxPageSize < GraphQL::Schema::Resolver
+ argument :name_includes, String, required: false
+ type Ship.connection_type, null: true
+
+ def resolve(name_includes: nil)
+ all_ships = object.ships.map { |ship_id| StarWars::DATA["Ship"][ship_id] }
+ if name_includes
+ all_ships = all_ships.select { |ship| ship.name.include?(name_includes)}
end
all_ships
end
-
- type Ship.connection_type
end
class ShipConnectionWithParentType < GraphQL::Types::Relay::BaseConnection
edge_type(Ship.edge_type)
field :parent_class_name, String, null: false
@@ -107,19 +107,37 @@
def parent_class_name
object.parent.class.name
end
end
+ class ShipsByResolver < GraphQL::Schema::Resolver
+ type ShipConnectionWithParentType, null: false
+
+ def resolve
+ object.ships.map { |ship_id| StarWars::DATA["Ship"][ship_id] }
+ end
+ end
+
class Faction < GraphQL::Schema::Object
implements GraphQL::Relay::Node.interface
- field :id, ID, null: false, resolve: GraphQL::Relay::GlobalIdResolve.new(type: Faction)
+ field :id, ID, null: false
+ def id
+ GraphQL::Relay::GlobalIdResolve.new(type: Faction).call(object, {}, context)
+ end
+
field :name, String, null: true
- field :ships, ShipConnectionWithParentType, connection: true, max_page_size: 1000, null: true, resolve: ->(obj, args, ctx) {
- all_ships = obj.ships.map {|ship_id| StarWars::DATA["Ship"][ship_id] }
- if args[:nameIncludes]
- case args[:nameIncludes]
+ field :ships, ShipConnectionWithParentType, connection: true, max_page_size: 1000, null: true do
+ argument :name_includes, String, required: false
+ end
+
+ field :shipsByResolver, resolver: ShipsByResolver, connection: true
+
+ def ships(name_includes: nil)
+ all_ships = object.ships.map {|ship_id| StarWars::DATA["Ship"][ship_id] }
+ if name_includes
+ case name_includes
when "error"
all_ships = GraphQL::ExecutionError.new("error from within connection")
when "raisedError"
raise GraphQL::ExecutionError.new("error raised from within connection")
when "lazyError"
@@ -130,33 +148,28 @@
all_ships = nil
when "lazyObject"
prev_all_ships = all_ships
all_ships = LazyWrapper.new { prev_all_ships }
else
- all_ships = all_ships.select { |ship| ship.name.include?(args[:nameIncludes])}
+ all_ships = all_ships.select { |ship| ship.name.include?(name_includes)}
end
end
all_ships
- } do
- # You can define arguments here and use them in the connection
- argument :nameIncludes, String, required: false
end
- field :shipsWithMaxPageSize, "Ships with max page size", max_page_size: 2, function: ShipsWithMaxPageSize.new
+ field :shipsWithMaxPageSize, "Ships with max page size", max_page_size: 2, resolver: ShipsWithMaxPageSize
- field :bases, BasesConnectionWithTotalCountType, null: true, connection: true, resolve: ->(obj, args, ctx) {
- all_bases = Base.where(id: obj.bases)
- if args[:nameIncludes]
- all_bases = all_bases.where("name LIKE ?", "%#{args[:nameIncludes]}%")
+ field :bases, BasesConnectionWithTotalCountType, null: true, connection: true do
+ argument :name_includes, String, required: false
+ end
+
+ def bases(name_includes: nil)
+ all_bases = Base.where(id: object.bases)
+ if name_includes
+ all_bases = all_bases.where("name LIKE ?", "%#{name_includes}%")
end
- if args[:complexOrder]
- all_bases = all_bases.order("bases.name DESC")
- end
all_bases
- } do
- argument :nameIncludes, String, required: false
- argument :complexOrder, Boolean, required: false
end
field :basesClone, BaseConnection, null: true
field :basesByName, BaseConnection, null: true do
argument :order, String, default_value: "name", required: false
@@ -167,17 +180,25 @@
else
@object.bases
end
end
- field :basesWithMaxLimitRelation, BaseConnection, null: true, max_page_size: 2, resolve: Proc.new { Base.all}
- field :basesWithMaxLimitArray, BaseConnection, null: true, max_page_size: 2, resolve: Proc.new { Base.all.to_a }
- field :basesWithDefaultMaxLimitRelation, BaseConnection, null: true, resolve: Proc.new { Base.all }
- field :basesWithDefaultMaxLimitArray, BaseConnection, null: true, resolve: Proc.new { Base.all.to_a }
- field :basesWithLargeMaxLimitRelation, BaseConnection, null: true, max_page_size: 1000, resolve: Proc.new { Base.all }
- field :basesWithoutNodes, BaseConnectionWithoutNodes, null: true, resolve: Proc.new { Base.all.to_a }
+ def all_bases
+ Base.all
+ end
+ def all_bases_array
+ all_bases.to_a
+ end
+
+ field :basesWithMaxLimitRelation, BaseConnection, null: true, max_page_size: 2, method: :all_bases
+ field :basesWithMaxLimitArray, BaseConnection, null: true, max_page_size: 2, method: :all_bases_array
+ field :basesWithDefaultMaxLimitRelation, BaseConnection, null: true, method: :all_bases
+ field :basesWithDefaultMaxLimitArray, BaseConnection, null: true, method: :all_bases_array
+ field :basesWithLargeMaxLimitRelation, BaseConnection, null: true, max_page_size: 1000, method: :all_bases
+ field :basesWithoutNodes, BaseConnectionWithoutNodes, null: true, method: :all_bases_array
+
field :basesAsSequelDataset, BasesConnectionWithTotalCountType, null: true, connection: true, max_page_size: 1000 do
argument :nameIncludes, String, required: false
end
def bases_as_sequel_dataset(name_includes: nil)
@@ -186,11 +207,15 @@
all_bases = all_bases.where(Sequel.like(:name, "%#{name_includes}%"))
end
all_bases
end
- field :basesWithCustomEdge, CustomEdgeBaseConnectionType, null: true, connection: true, resolve: ->(o, a, c) { LazyNodesWrapper.new(o.bases) }
+ field :basesWithCustomEdge, CustomEdgeBaseConnectionType, null: true, connection: true, method: :lazy_bases
+
+ def lazy_bases
+ LazyNodesWrapper.new(object.bases)
+ end
end
class IntroduceShipMutation < GraphQL::Schema::RelayClassicMutation
description "Add a ship to this faction"
@@ -202,63 +227,36 @@
field :ship_edge, Ship.edge_type, null: true
field :faction, Faction, null: true
field :aliased_faction, Faction, hash_key: :aliased_faction, null: true
def resolve(ship_name: nil, faction_id:)
- IntroduceShipFunction.new.call(object, {ship_name: ship_name, faction_id: faction_id}, context)
- end
- end
-
- class IntroduceShipFunction < GraphQL::Function
- description "Add a ship to this faction"
-
- argument :shipName, GraphQL::STRING_TYPE
- argument :factionId, !GraphQL::ID_TYPE
-
- type(GraphQL::ObjectType.define do
- name "IntroduceShipFunctionPayload"
- field :shipEdge, Ship.edge_type, hash_key: :shipEdge
- field :faction, Faction, hash_key: :shipEdge
- end)
-
- def call(obj, args, ctx)
- # support old and new args
- ship_name = args["shipName"] || args[:ship_name]
- faction_id = args["factionId"] || args[:faction_id]
if ship_name == 'Millennium Falcon'
GraphQL::ExecutionError.new("Sorry, Millennium Falcon ship is reserved")
elsif ship_name == 'Leviathan'
raise GraphQL::ExecutionError.new("🔥")
elsif ship_name == "Ebon Hawk"
LazyWrapper.new { raise GraphQL::ExecutionError.new("💥")}
else
ship = DATA.create_ship(ship_name, faction_id)
faction = DATA["Faction"][faction_id]
connection_class = GraphQL::Relay::BaseConnection.connection_for_nodes(faction.ships)
- ships_connection = connection_class.new(faction.ships, args)
+ ships_connection = connection_class.new(faction.ships, {ship_name: ship_name, faction: faction})
ship_edge = GraphQL::Relay::Edge.new(ship, ships_connection)
result = {
- shipEdge: ship_edge,
ship_edge: ship_edge, # support new-style, too
faction: faction,
aliased_faction: faction,
}
- if args["shipName"] == "Slave II"
+ if ship_name == "Slave II"
LazyWrapper.new(result)
else
result
end
end
end
end
- IntroduceShipFunctionMutation = GraphQL::Relay::Mutation.define do
- # Used as the root for derived types:
- name "IntroduceShipFunction"
- function IntroduceShipFunction.new
- end
-
# GraphQL-Batch knockoff
class LazyLoader
def self.defer(ctx, model, id)
ids = ctx.namespace(:loading)[model] ||= []
ids << id
@@ -316,39 +314,80 @@
GraphQL::Relay::BaseConnection.register_connection_implementation(LazyNodesWrapper, LazyNodesRelationConnection)
class QueryType < GraphQL::Schema::Object
graphql_name "Query"
- field :rebels, Faction, null: true, resolve: ->(obj, args, ctx) { StarWars::DATA["Faction"]["1"]}
+ field :rebels, Faction, null: true
+ def rebels
+ StarWars::DATA["Faction"]["1"]
+ end
- field :empire, Faction, null: true, resolve: ->(obj, args, ctx) { StarWars::DATA["Faction"]["2"]}
+ field :empire, Faction, null: true
+ def empire
+ StarWars::DATA["Faction"]["2"]
+ end
- field :largestBase, BaseType, null: true, resolve: ->(obj, args, ctx) { Base.find(3) }
+ field :largestBase, BaseType, null: true
- field :newestBasesGroupedByFaction, BaseConnection, null: true, resolve: ->(obj, args, ctx) {
+ def largest_base
+ Base.find(3)
+ end
+
+ field :newestBasesGroupedByFaction, BaseConnection, null: true
+
+ def newest_bases_grouped_by_faction
Base
.having('id in (select max(id) from bases group by faction_id)')
.group(:id)
.order('faction_id desc')
- }
+ end
- field :basesWithNullName, BaseConnection, null: false, resolve: ->(obj, args, ctx) {
+ field :basesWithNullName, BaseConnection, null: false
+
+ def bases_with_null_name
[OpenStruct.new(id: nil)]
- }
+ end
- field :node, field: GraphQL::Relay::Node.field
+ if TESTING_INTERPRETER
+ add_field(GraphQL::Types::Relay::NodeField)
+ else
+ field :node, field: GraphQL::Relay::Node.field
+ end
- custom_node_field = GraphQL::Relay::Node.field do
- resolve ->(_, _, _) { StarWars::DATA["Faction"]["1"] }
+ if TESTING_INTERPRETER
+ field :node_with_custom_resolver, GraphQL::Types::Relay::Node, null: true do
+ argument :id, ID, required: true
+ end
+ def node_with_custom_resolver(id:)
+ StarWars::DATA["Faction"]["1"]
+ end
+ else
+ custom_node_field = GraphQL::Relay::Node.field do
+ resolve ->(_, _, _) { StarWars::DATA["Faction"]["1"] }
+ end
+ field :nodeWithCustomResolver, field: custom_node_field
end
- field :nodeWithCustomResolver, field: custom_node_field
- field :nodes, field: GraphQL::Relay::Node.plural_field
- field :nodesWithCustomResolver, field: GraphQL::Relay::Node.plural_field(
- resolve: ->(_, _, _) { [StarWars::DATA["Faction"]["1"], StarWars::DATA["Faction"]["2"]] }
- )
+ if TESTING_INTERPRETER
+ add_field(GraphQL::Types::Relay::NodesField)
+ else
+ field :nodes, field: GraphQL::Relay::Node.plural_field
+ end
+ if TESTING_INTERPRETER
+ field :nodes_with_custom_resolver, [GraphQL::Types::Relay::Node, null: true], null: true do
+ argument :ids, [ID], required: true
+ end
+ def nodes_with_custom_resolver(ids:)
+ [StarWars::DATA["Faction"]["1"], StarWars::DATA["Faction"]["2"]]
+ end
+ else
+ field :nodesWithCustomResolver, field: GraphQL::Relay::Node.plural_field(
+ resolve: ->(_, _, _) { [StarWars::DATA["Faction"]["1"], StarWars::DATA["Faction"]["2"]] }
+ )
+ end
+
field :batchedBase, BaseType, null: true do
argument :id, ID, required: true
end
def batched_base(id:)
@@ -357,11 +396,10 @@
end
class MutationType < GraphQL::Schema::Object
graphql_name "Mutation"
field :introduceShip, mutation: IntroduceShipMutation
- field :introduceShipFunction, field: IntroduceShipFunctionMutation.field
end
class ClassNameRecorder
def initialize(context_key)
@context_key = context_key
@@ -384,9 +422,13 @@
class Schema < GraphQL::Schema
query(QueryType)
mutation(MutationType)
default_max_page_size 3
+
+ if TESTING_INTERPRETER
+ use GraphQL::Execution::Interpreter
+ end
def self.resolve_type(type, object, ctx)
if object == :test_error
:not_a_type
elsif object.is_a?(Base)