Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: return absolute media URLs from GraphQL #4565

Merged
merged 17 commits into from
Sep 4, 2018

Conversation

dancastellon
Copy link
Contributor

@dancastellon dancastellon commented Aug 21, 2018

Resolves #4543
Impact: minor
Type: feature

Issue

Currently GraphQL returns relative media URLs. Because of this, storefront needs to prepend the returned paths with the Meteor server's base URL.

Solution

Implement the currently unused xformProductMedia function in resolvers to prepend media URLs with the server's base URL. This will allow us in the future to take account for CDNs.

Breaking changes

None

Testing

  1. Catalog Image URLs
    • Create a product and upload some images. Click on a variant option and add images to that option. Publish product.
    • Query GraphQL
{
  catalogItems(shopIds: ["cmVhY3Rpb24vc2hvcDpKOEJocTN1VHRkZ3daeDNyeg=="]) {
    edges {
      node {
        createdAt
        updatedAt
        ... on CatalogItemProduct {
          product {
            media {
              URLs {
                large
                medium
                original
                small
                thumbnail
              }
            }
            primaryImage {
              URLs {
                large
                medium
                original
                small
                thumbnail
              }
            }
            variants {
              media {
                URLs {
                  large
                  medium
                  original
                  small
                  thumbnail
                }
              }
              primaryImage {
                URLs {
                  large
                  medium
                  original
                  small
                  thumbnail
                }
              }
              options {
                media {
                  URLs {
                    large
                    medium
                    original
                    small
                    thumbnail
                  }
                }
                primaryImage {
                  URLs {
                    large
                    medium
                    original
                    small
                    thumbnail
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
  • Confirm image URLs are absolute (and correct)
  1. Cart Image URLs
    • Add an item to your cart that has an image
    • Query GraphQL
accountCartByAccountId(
    accountId: “...",
    shopId: “..."
  ) {
    items {
      edges {
        node {
          imageURLs {
            large
            medium
            original
            small
            thumbnail
          }
        }
      }
    }
  }
  • Confirm image URLs are absolute (and correct)
  1. Imports/plugins/core/cart/server/methods/addToCart.js
  • After context on line 38, add logging:
  console.log("context user:", context.user);
  console.log("context rootUrl:", context.rootUrl);
  console.log("context getAbsoluteUrl:", context.getAbsoluteUrl("test"));
  • Add something to your cart and confirm server log shows correct context user, root url, and absolute url

@dancastellon dancastellon changed the base branch from master to release-1.15.0 August 21, 2018 14:15
const { metadata, large, medium, image, small, thumbnail } = mediaItem;

const { priority, toGrid, productId, variantId, URLs: { large, medium, original, small, thumbnail } } = mediaItem;
const absoluteUrl = Reaction.absoluteUrl().slice(0, -1);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aldeed Is this all that's needed? How can I take into account when a CDN is being used?

@dancastellon dancastellon changed the title feat: return absolute media URLs from GraphQL WIP feat: return absolute media URLs from GraphQL Aug 21, 2018
@dancastellon dancastellon changed the title WIP feat: return absolute media URLs from GraphQL feat: return absolute media URLs from GraphQL Aug 23, 2018
primaryImage: (node, args, context) => xformProductMedia(node.primaryImage, context),
variants: (node, args, context) => node.variants.map((variant) => {
variant.media = variant.media.map((mediaItem) => xformProductMedia(mediaItem, context));
variant.primaryImage = xformProductMedia(variant.primaryImage, context);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variants can have options, which have the same schema as variants. if (variant.options) then do the same map on the options.

* @param {String} request.protocol Either http or https
* @returns {String} URL
*/
export default function getAbsoluteUrl(request) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to how the current Reaction.absoluteUrl function works, this should take an optional path arg and then do the work of properly appending that path. It should check if it starts with / and remove it so that we don't end up with two /.

In your xform you will then do something like large: context.getAbsoluteUrl(large).

Actually, performance wise, it's best if you have two different functions. This function you have now would be called only one time in buildContext. You could actually set the result of that on context, too, as rootUrl. Then context.getAbsoluteUrl would only do the work to combine root url with path. Something like:

function buildContext() {
  context.rootUrl = getRootUrl(request); // this is the function you currently have, renamed
  context.getAbsoluteUrl = (path) => getAbsoluteUrl(context.rootUrl, path); // this just combines the strings intelligently
}

@dancastellon dancastellon changed the title feat: return absolute media URLs from GraphQL WIP feat: return absolute media URLs from GraphQL Aug 24, 2018
@dancastellon
Copy link
Contributor Author

@aldeed Thanks, changes made!

@dancastellon dancastellon changed the title WIP feat: return absolute media URLs from GraphQL feat: return absolute media URLs from GraphQL Aug 24, 2018
@aldeed aldeed changed the base branch from release-1.15.0 to release-1.16.0 August 30, 2018 16:56
@aldeed aldeed added this to the Little Bear milestone Aug 31, 2018
@aldeed
Copy link
Contributor

aldeed commented Aug 31, 2018

Not merging yet because we should merge this around the same time as the starter kit PR: reactioncommerce/example-storefront#243

@spencern spencern modified the milestones: Little Bear, Massive Sep 4, 2018
@aldeed aldeed merged commit 4356638 into release-1.16.0 Sep 4, 2018
@aldeed aldeed deleted the feat-4543-dancastellon-absolute-media-urls branch September 4, 2018 23:15
@spencern spencern mentioned this pull request Sep 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants