I will start with some GraphQL basics, then dig into process of metaprogramming a GraphQL layer from a demo ruby server. I will explain the benefits of using this design pattern and how it improves developer experience.
(Sets) $14,000 3/10/2014 23 Diamond Custom Cuts $200,000 3/10/2014 43 Classic Open Face $230,000 3/10/2014 12 Solid Classics $9,000 3/10/2014 11 Promo Duration Promo Details # Promos used Breezey Promo 3/21/2014 - Forever xx off Loyalty 22 Full Set Discount 3/21/2014 - 4/12/2014 xx% off full set 12 Deposits Pending: $XX Devices: XX # Employees: XX Gift Cards Has Loans Subscriptions # Payments Received Marketing Plans Appointments Chargebacks And So Much More … # Refunds Grillz by Nelly en-US St. Louis, MO Freeze Deactivate Audit Actions: Resolve Unfreeze Payments Graph
1 class Types::PaymentType < Types::BaseObject 2 field :id, ID, null: false 3 field :amount, Int, null: false 4 field :merchant, Types::MerchantType, null: false 5 end
1 class Types::PaymentType < Types::BaseObject 2 field :id, ID, null: false 3 field :amount, Int, null: false 4 field :merchant, Types::MerchantType, null: false 5 end
. 13 gql_type_generator 14 .target_to_gql_class_mapping.each do |target, gql_type| 15 field_name = target.to_s.downcase.to_sym 16 field field_name, gql_type, null: false do 17 argument :id, ID, required: true 18 end 24 end 25 end 26 end 27 3 field :payment, Types::PaymentType, null: false do 4 argument :id, ID, required: true 5 end
. 13 gql_type_generator 14 .target_to_gql_class_mapping.each do |target, gql_type| 15 field_name = target.to_s.downcase.to_sym 16 field field_name, gql_type, null: false do 17 argument :id, ID, required: true 18 end 24 end 25 end 26 end 27 3 field :payment, Types::PaymentType, null: false do 4 argument :id, ID, required: true 5 end
. 13 gql_type_generator 14 .target_to_gql_class_mapping.each do |target, gql_type| 15 field_name = target.to_s.downcase.to_sym 16 field field_name, gql_type, null: false do 17 argument :id, ID, required: true 18 end 24 end 25 end 26 end 27 3 field :payment, Types::PaymentType, null: false do 4 argument :id, ID, required: true 5 end
. 13 gql_type_generator 14 .target_to_gql_class_mapping.each do |target, gql_type| 15 field_name = target.to_s.downcase.to_sym 16 field field_name, gql_type, null: false do 17 argument :id, ID, required: true 18 end 24 end 25 end 26 end 27 3 field :payment, Types::PaymentType, null: false do 4 argument :id, ID, required: true 5 end
'creates a Target Class to GqlType Class mapping' do 5 all_target_classes = Target.all_target_classes 6 all_target_classes.each do |target_class| 7 expect{ "Types::#{target_class.to_s}Type".constantize }.to raise_error(NameError) 8 end 9 10 util = GqlTypeGenerator.new(all_target_classes) 11 12 all_target_classes.each do |target_class| 13 gql_type_class_name = "Types::#{target_class.to_s}Type".constantize 14 expect(gql_type_class_name).to be_instance_of Class 15 util.target_to_gql_class_mapping[target_class] = gql_type_class_name 16 end 17 end 18 end
'creates a Target Class to GqlType Class mapping' do 5 all_target_classes = Target.all_target_classes 6 all_target_classes.each do |target_class| expect{ "Types::#{target_class.to_s}Type".constantize }.to raise_error(NameError) 8 end 9 10 util = GqlTypeGenerator.new(all_target_classes) 11 12 all_target_classes.each do |target_class| 13 gql_type_class_name = "Types::#{target_class.to_s}Type".constantize 14 expect(gql_type_class_name).to be_instance_of Class 15 util.target_to_gql_class_mapping[target_class] = gql_type_class_name 16 end 17 end 18 end
'creates a Target Class to GqlType Class mapping' do 5 all_target_classes = Target.all_target_classes 6 all_target_classes.each do |target_class| 7 expect{ "Types::#{target_class.to_s}Type".constantize }.to raise_error(NameError) 8 end 9 10 util = GqlTypeGenerator.new(all_target_classes) 11 12 all_target_classes.each do |target_class| 13 gql_type_class_name = "Types::#{target_class.to_s}Type".constantize 14 expect(gql_type_class_name).to be_instance_of Class 15 util.target_to_gql_class_mapping[target_class] = gql_type_class_name 16 end 17 end 18 end
'creates a Target Class to GqlType Class mapping' do 5 all_target_classes = Target.all_target_classes 6 all_target_classes.each do |target_class| 7 expect{ "Types::#{target_class.to_s}Type".constantize }.to raise_error(NameError) 8 end 9 10 gql_type_generator = GqlTypeGenerator.new(all_target_classes) 11 12 all_target_classes.each do |target_class| 13 gql_type_class_name = "Types::#{target_class.to_s}Type".constantize 14 expect(gql_type_class_name).to be_instance_of Class 15 util.target_to_gql_class_mapping[target_class] = gql_type_class_name 16 end 17 end 18 end
'creates a Target Class to GqlType Class mapping' do 5 all_target_classes = Target.all_target_classes 6 all_target_classes.each do |target_class| 7 expect{ "Types::#{target_class.to_s}Type".constantize }.to raise_error(NameError) 8 end 9 gql_type_generator = GqlTypeGenerator.new(all_target_classes) 11 12 all_target_classes.each do |target_class| 13 gql_type_class_name = "Types::#{target_class.to_s}Type".constantize 14 expect(gql_type_class_name).to be_instance_of Class 15 util.target_to_gql_class_mapping[target_class] = gql_type_class_name 16 end 17 end 18 end
'creates a Target Class to GqlType Class mapping' do 5 all_target_classes = Target.all_target_classes 6 all_target_classes.each do |target_class| 7 expect{ "Types::#{target_class.to_s}Type".constantize }.to raise_error(NameError) 8 end 9 10 gql_type_generator = GqlTypeGenerator.new(all_target_classes) 11 12 all_target_classes.each do |target_class| 13 gql_type_class_name = "Types::#{target_class.to_s}Type".constantize 14 expect(gql_type_class_name).to be_instance_of Class 15 util.target_to_gql_class_mapping[target_class] = gql_type_class_name 16 end 17 end 18 end
'creates a Target Class to GqlType Class mapping' do 5 all_target_classes = Target.all_target_classes 6 all_target_classes.each do |target_class| 7 expect{ "Types::#{target_class.to_s}Type".constantize }.to raise_error(NameError) 8 end 9 10 gql_type_generator = GqlTypeGenerator.new(all_target_classes) 11 12 all_target_classes.each do |target_class| 13 gql_type_class_name = "Types::#{target_class.to_s}Type".constantize 14 expect(gql_type_class_name).to be_instance_of Class 15 gql_type_generator.target_to_gql_class_mapping[target_class] = gql_type_class_name 16 end 17 end 18 end
'creates a Target Class to GqlType Class mapping' do 5 all_target_classes = Target.all_target_classes 6 all_target_classes.each do |target_class| 7 expect{ "Types::#{target_class.to_s}Type".constantize }.to raise_error(NameError) 8 end 9 10 gql_type_generator = GqlTypeGenerator.new(all_target_classes) 11 12 all_target_classes.each do |target_class| 13 gql_type_class_name = "Types::#{target_class.to_s}Type".constantize expect(gql_type_class_name).to be_instance_of Class gql_type_generator.target_to_gql_class_mapping[target_class] = gql_type_class_name 16 end 17 end 18 end