Last active
August 24, 2021 05:57
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks to this StackOverflow answer for the inspiration: https://stackoverflow.com/a/57262111/1619602