Shopify Storefront GraphQL

Cliente headless: PetStore Vion  ·  Storefront API 2025-01  ·  3 operaciones generadas y validadas

API 2025-01 Validado
10:14:02SEARCHsearch_docs.mjs "product by handle with variants" → 4 resultados
10:14:03SEARCHsearch_docs.mjs "cart create add lines mutation" → 6 resultados
10:14:05BUILDGenerando 3 operaciones GraphQL mínimas…
10:14:07VALIDvalidate.mjs artifact-a1b2 rev1 → PASS (0 errores, 0 advertencias)
10:14:08VALIDvalidate.mjs artifact-c3d4 rev1 → PASS
10:14:09VALIDvalidate.mjs artifact-e5f6 rev1 → PASS
Query

Obtener producto por handle con variantes y precios

docs.shopify.com/api/storefront/2025-01/queries/product ↗
# Busca un producto por su handle y retorna variantes con precio y stock
query ProductByHandle($handle: String!, $country: CountryCode!)
@inContext(country: $country) {
  product(handle: $handle) {
    id
    title
    descriptionHtml
    featuredImage {
      url
      altText
    }
    variants(first: 10) {
      nodes {
        id
        title
        availableForSale
        quantityAvailable
        price {
          amount
          currencyCode
        }
        compareAtPrice {
          amount
          currencyCode
        }
        selectedOptions {
          name
          value
        }
      }
    }
  }
}

Notas de implementación

  • Se usa @inContext para obtener precios localizados por país sin query adicional.
  • variants(first: 10) es suficiente para la mayoría de productos; aumentar solo si el catálogo lo requiere.
  • compareAtPrice permite mostrar descuentos sin cálculo en cliente.
  • Ref: ProductVariant.quantityAvailable devuelve null si el inventario no está rastreado — tratar como disponible.
Mutation

Crear carrito y añadir líneas en una sola operación

docs.shopify.com/api/storefront/2025-01/mutations/cartCreate ↗
# Crea el carrito con los primeros artículos (evita cartCreate + cartLinesAdd por separado)
mutation CartCreate($lines: [CartLineInput!]!, $buyerIdentity: CartBuyerIdentityInput) {
  cartCreate(
    input: {
      lines: $lines
      buyerIdentity: $buyerIdentity
    }
  ) {
    cart {
      id
      checkoutUrl
      totalQuantity
      cost {
        subtotalAmount { amount currencyCode }
        totalTaxAmount { amount currencyCode }
      }
      lines(first: 50) {
        nodes {
          id
          quantity
          merchandise {
            ... on ProductVariant {
              id
              title
              price { amount currencyCode }
            }
          }
        }
      }
    }
    userErrors {
      field
      message
      code
    }
  }
}

Notas de implementación

  • Usar cartCreate con lines en el input en lugar de cartCreate + cartLinesAdd separados (reduce 1 round-trip).
  • Persistir cart.id en cookie httpOnly o sessionStorage para reconectar el carrito entre páginas.
  • Siempre leer userErrors: errores de variante agotada o límite de cantidad se devuelven aquí, no como errores HTTP.
  • checkoutUrl redirige directamente al checkout nativo de Shopify (no requiere implementación propia).
Mutation

Actualizar cantidad de línea en carrito existente

docs.shopify.com/api/storefront/2025-01/mutations/cartLinesUpdate ↗
# Actualiza la cantidad de una o varias líneas (quantity: 0 elimina la línea)
mutation CartLinesUpdate($cartId: ID!, $lines: [CartLineUpdateInput!]!) {
  cartLinesUpdate(cartId: $cartId, lines: $lines) {
    cart {
      id
      totalQuantity
      cost {
        subtotalAmount { amount currencyCode }
      }
      lines(first: 50) {
        nodes {
          id
          quantity
          cost {
            totalAmount { amount }
          }
        }
      }
    }
    userErrors { field message }
  }
}

Notas de implementación

  • Pasar quantity: 0 elimina la línea — no hace falta llamar a cartLinesRemove para ese caso.
  • Se puede actualizar varias líneas en una sola mutation pasando array en $lines.
  • Devolver solo totalAmount por línea (no todos los campos de precio) minimiza el payload de respuesta.

Variables de ejemplo

JSON
{
  // ProductByHandle
  "handle": "pienso-premium-senior-labrador",
  "country": "ES",

  // CartCreate
  "lines": [
    {
      "merchandiseId": "gid://shopify/ProductVariant/44892012781786",
      "quantity": 2
    }
  ],
  "buyerIdentity": {
    "countryCode": "ES"
  },

  // CartLinesUpdate
  "cartId": "gid://shopify/Cart/c1-abc123def456",
  "lines": [{
    "id": "gid://shopify/CartLine/abc123",
    "quantity": 3
  }]
}

Validación completada — 3/3 operaciones aprobadas

Todas las operaciones han pasado la validación contra el schema de Storefront API 2025-01. Cero errores de tipo, campos obsoletos ni argumentos incorrectos.

model: claude-sonnet-4-6 client: claude-code artifact-a1b2 rev1 artifact-c3d4 rev1 artifact-e5f6 rev1