Skip to content

Instantly share code, notes, and snippets.

@forsbergplustwo
Last active August 24, 2021 05:57
Show Gist options
  • Save forsbergplustwo/ced44775dbfd7ad8dd0dee2f57028902 to your computer and use it in GitHub Desktop.
Save forsbergplustwo/ced44775dbfd7ad8dd0dee2f57028902 to your computer and use it in GitHub Desktop.
Proof of concept! Transforms Shopify GraphQL API responses to remove the need to type "edges" and "node", while also adding support for Ruby dot notation. We could also transform createAt to created_at.. but I think that will be "too much magic", as it won't match docs etc.
require 'json'
class GraphqlResponseRubyfier
def initialize(response)
@response = JSON.parse(response)
end
def rubyfy
rubyfied_response = to_o(@response)
puts(rubyfied_response)
puts(rubyfied_response.data.product.collections.collect(&:handle))
rubyfied_response
end
def to_o(obj)
if obj.is_a?(Hash) && obj['edges']
to_o(obj['edges'])
elsif obj.is_a?(Hash)
OpenStruct.new(obj.map { |key, val| [key, to_o(val)] }.to_h)
elsif obj.is_a?(Array)
obj.map { |o| o['node'] ? to_o(o['node']) : to_o(o) }
else
obj
end
end
end
EXAMPLE_RESPONSE = "{\r\n \"data\": {\r\n \"product\": {\r\n \"availablePublicationCount\": 3,\r\n \"collections\": {\r\n \"edges\": [\r\n {\r\n \"node\": {\r\n \"handle\": \"great-gifts\"\r\n }\r\n }\r\n ]\r\n },\r\n \"createdAt\": \"2017-09-18T14:05:28Z\",\r\n \"defaultCursor\": \"eyJsaW1pdCI6MSwib3JkZXIiOiJpZCBhc2MiLCJsYXN0X2lkIjoxMDUyMTU3ODYyNiwibGFzdF92YWx1ZSI6MTA1MjE1Nzg2MjYsImRpcmVjdGlvbiI6Im5leHQifQ==\",\r\n \"description\": \"This t-shirt comes in a range of colors. It's made with super-soft combed cotton and a slim fit. Cotton-blend thread in the seams guarantees an even dye.\",\r\n \"descriptionHtml\": \"<meta charset=\\\"utf-8\\\"><span>This t-shirt comes in a range of colors. It's made with super-soft combed cotton and a slim fit. Cotton-blend thread in the seams guarantees an even dye.<\/span>\",\r\n \"featuredImage\": {\r\n \"id\": \"gid:\/\/shopify\/ProductImage\/23213976514\"\r\n },\r\n \"feedback\": {\r\n \"details\": []\r\n },\r\n \"giftCardTemplateSuffix\": null,\r\n \"handle\": \"classic-crew-neck\",\r\n \"hasOnlyDefaultVariant\": false,\r\n \"hasOutOfStockVariants\": false,\r\n \"id\": \"gid:\/\/shopify\/Product\/10521578626\",\r\n \"images\": {\r\n \"edges\": [\r\n {\r\n \"node\": {\r\n \"id\": \"gid:\/\/shopify\/ProductImage\/23213976514\"\r\n }\r\n },\r\n {\r\n \"node\": {\r\n \"id\": \"gid:\/\/shopify\/ProductImage\/23213976578\"\r\n }\r\n },\r\n {\r\n \"node\": {\r\n \"id\": \"gid:\/\/shopify\/ProductImage\/23213976642\"\r\n }\r\n }\r\n ]\r\n },\r\n \"inCollection\": false,\r\n \"isGiftCard\": false,\r\n \"legacyResourceId\": \"10521578626\",\r\n \"metafield\": null,\r\n \"metafields\": {\r\n \"edges\": []\r\n },\r\n \"onlineStorePreviewUrl\": \"https:\/\/test-shop.myshopify.com\/products\/classic-crew-neck\",\r\n \"onlineStoreUrl\": \"https:\/\/test-shop.myshopify.com\/products\/classic-crew-neck\",\r\n \"options\": [\r\n {\r\n \"name\": \"Size\"\r\n },\r\n {\r\n \"name\": \"Color\"\r\n }\r\n ],\r\n \"priceRange\": {\r\n \"maxVariantPrice\": {\r\n \"amount\": \"4200.0\"\r\n },\r\n \"minVariantPrice\": {\r\n \"amount\": \"4200.0\"\r\n }\r\n },\r\n \"productType\": \"\",\r\n \"publicationCount\": 4,\r\n \"publishedAt\": \"2017-09-18T14:05:17Z\",\r\n \"resourcePublications\": {\r\n \"edges\": [\r\n {\r\n \"node\": {\r\n \"isPublished\": true\r\n }\r\n },\r\n {\r\n \"node\": {\r\n \"isPublished\": true\r\n }\r\n },\r\n {\r\n \"node\": {\r\n \"isPublished\": true\r\n }\r\n }\r\n ]\r\n },\r\n \"seo\": {\r\n \"title\": null\r\n },\r\n \"storefrontId\": \"Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0LzEwNTIxNTc4NjI2\",\r\n \"tags\": [],\r\n \"templateSuffix\": null,\r\n \"title\": \"Classic crew neck\",\r\n \"totalInventory\": 12,\r\n \"totalVariants\": 6,\r\n \"tracksInventory\": true,\r\n \"unpublishedPublications\": {\r\n \"edges\": [\r\n {\r\n \"node\": {\r\n \"name\": \"Google Shopping\"\r\n }\r\n }\r\n ]\r\n },\r\n \"updatedAt\": \"2019-01-23T01:35:15Z\",\r\n \"variants\": {\r\n \"edges\": [\r\n {\r\n \"node\": {\r\n \"displayName\": \"Classic crew neck - Small \/ Blue\"\r\n }\r\n },\r\n {\r\n \"node\": {\r\n \"displayName\": \"Classic crew neck - Small \/ Green\"\r\n }\r\n },\r\n {\r\n \"node\": {\r\n \"displayName\": \"Classic crew neck - Medium \/ Blue\"\r\n }\r\n }\r\n ]\r\n },\r\n \"vendor\": \"John's Apparel\"\r\n }\r\n }\r\n }".freeze
GraphqlResponseRubyfier.new(EXAMPLE_RESPONSE).rubyfy
# Useage: ruby graphql_response_rubyfier.rb
# Outputs:
# <OpenStruct data=#<OpenStruct product=#<OpenStruct availablePublicationCount=3, collections=[#<OpenStruct handle="great-gifts">], createdAt="2017-09-18T14:05:28Z", defaultCursor="eyJsaW1pdCI6MSwib3JkZXIiOiJpZCBhc2MiLCJsYXN0X2lkIjoxMDUyMTU3ODYyNiwibGFzdF92YWx1ZSI6MTA1MjE1Nzg2MjYsImRpcmVjdGlvbiI6Im5leHQifQ==", description="This t-shirt comes in a range of colors. It's made with super-soft combed cotton and a slim fit. Cotton-blend thread in the seams guarantees an even dye.", descriptionHtml="<meta charset=\"utf-8\"><span>This t-shirt comes in a range of colors. It's made with super-soft combed cotton and a slim fit. Cotton-blend thread in the seams guarantees an even dye.</span>", featuredImage=#<OpenStruct id="gid://shopify/ProductImage/23213976514">, feedback=#<OpenStruct details=[]>, giftCardTemplateSuffix=nil, handle="classic-crew-neck", hasOnlyDefaultVariant=false, hasOutOfStockVariants=false, id="gid://shopify/Product/10521578626", images=[#<OpenStruct id="gid://shopify/ProductImage/23213976514">, #<OpenStruct id="gid://shopify/ProductImage/23213976578">, #<OpenStruct id="gid://shopify/ProductImage/23213976642">], inCollection=false, isGiftCard=false, legacyResourceId="10521578626", metafield=nil, metafields=[], onlineStorePreviewUrl="https://test-shop.myshopify.com/products/classic-crew-neck", onlineStoreUrl="https://test-shop.myshopify.com/products/classic-crew-neck", options=[nil, nil], priceRange=#<OpenStruct maxVariantPrice=#<OpenStruct amount="4200.0">, minVariantPrice=#<OpenStruct amount="4200.0">>, productType="", publicationCount=4, publishedAt="2017-09-18T14:05:17Z", resourcePublications=[#<OpenStruct isPublished=true>, #<OpenStruct isPublished=true>, #<OpenStruct isPublished=true>], seo=#<OpenStruct title=nil>, storefrontId="Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0LzEwNTIxNTc4NjI2", tags=[], templateSuffix=nil, title="Classic crew neck", totalInventory=12, totalVariants=6, tracksInventory=true, unpublishedPublications=[#<OpenStruct name="Google Shopping">], updatedAt="2019-01-23T01:35:15Z", variants=[#<OpenStruct displayName="Classic crew neck - Small / Blue">, #<OpenStruct displayName="Classic crew neck - Small / Green">, #<OpenStruct displayName="Classic crew neck - Medium / Blue">], vendor="John's Apparel">>>
# "great-gifts"
@forsbergplustwo
Copy link
Author

Thanks to this StackOverflow answer for the inspiration: https://stackoverflow.com/a/57262111/1619602

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment