Skip to content

Instantly share code, notes, and snippets.

@rmosolgo
Created December 5, 2022 15:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rmosolgo/52d513286848aa21f7d3a3dd4a1b8c59 to your computer and use it in GitHub Desktop.
Save rmosolgo/52d513286848aa21f7d3a3dd4a1b8c59 to your computer and use it in GitHub Desktop.
Moving legacy fields to a GraphQL::Enterprise::Changeset
require "bundler/inline"
gemfile do
gem "graphql", path: "./"
gem "graphql-enterprise", source: "https://gems.graphql.pro"
end
class BaseField < GraphQL::Schema::Field
include GraphQL::Enterprise::Changeset::FieldIntegration
end
class Thing < GraphQL::Schema::Object
field_class BaseField
end
class Query < GraphQL::Schema::Object
field :thing, Thing
def thing
{ legacy_message: "Ye Olde Message", new_message: "Yo!" }
end
end
# Make a changeset which includes legacy fields, and choose a long-past date for this version
class LegacyFields < GraphQL::Enterprise::Changeset
release "1900-01-01"
modifies Thing do
field :legacy_message, String
end
end
class ModernFields < GraphQL::Enterprise::Changeset
release "2022-12-01"
modifies Thing do
field :new_message, String
remove_field :legacy_message
end
end
class Schema < GraphQL::Schema
query(Query)
use GraphQL::Enterprise::Changeset::Release, changesets: [LegacyFields, ModernFields]
end
# Here's the catch: `changeset_version: nil` won't work as a default, because it will
# go back to _before_ the legacy changeset above. So instead, update your application to
# use a default `changeset_version` which is between the long-past legacy changeset
# and the first "real," new-feature changeset.
pp Schema.execute("{ thing { legacyMessage } }", context: { changeset_version: "2000-01-01" }).to_h
# {"data"=>{"thing"=>{"legacyMessage"=>"Ye Olde Message"}}}
puts Schema.to_definition(context: { changeset_version: "2000-01-01" })
# type Query {
# thing: Thing
# }
#
# type Thing {
# legacyMessage: String
# }
# Then, future changeset won't see legacy fields:
pp Schema.execute("{ thing { newMessage } }", context: { changeset_version: "2023-12-01" }).to_h
# {"data"=>{"thing"=>{"newMessage"=>"Yo!"}}}
puts Schema.to_definition(context: { changeset_version: "2023-01-01" })
# type Query {
# thing: Thing
# }
# type Thing {
# newMesssage: String
# }
# { changeset_version: nil } won't work, since the legacy fields won't be on the type:
pp Schema.execute("{ thing { legacyMessage } }", context: { changeset_version: nil }).to_h
# {"errors"=>
# [{"message"=>"Field 'legacyMessage' doesn't exist on type 'Thing'",
# "locations"=>[{"line"=>1, "column"=>11}],
# "path"=>["query", "thing", "legacyMessage"],
# "extensions"=>{"code"=>"undefinedField", "typeName"=>"Thing", "fieldName"=>"legacyMessage"}}]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment