Creación de productos con HTTP POST y fetch

Clase 14 de 17Curso de API REST con Javascript

Resumen

Aprende a crear un nuevo producto con HTTP POST usando fetch y un patrón de repositorio en JavaScript. Aquí verás cómo definir el body, configurar headers, validar la respuesta y conectar el flujo con un formulario de creación, todo paso a paso y sin complicaciones.

¿Cómo crear productos con HTTP post y fetch?

Para crear un producto, la URL del endpoint es la misma que la de listar productos; lo que cambia es el verbo HTTP: POST. El body debe seguir la especificación del API: título, precio, descripción, categoryId e images (lista de URLs en formato string).

Ejemplo del método en el repositorio usando async/await y fetch:

// Dentro del repositorio de productos
async function createProduct(product) {
  const url = PRODUCTS_URL; // misma URL que GET de productos.

  const response = await fetch(url, {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(product),
  });

  if (!response.ok) {
    throw new Error(`No se pudo crear el producto: status code=${response.status}`);
  }

  const jsonResponse = await response.json();
  return jsonResponse;
}

¿Qué body y headers requiere el endpoint de productos?

  • Enviar un objeto con forma de API: title, price, description, categoryId, images.
  • Usar JSON.stringify(product) para serializar el body.
  • Incluir headers: Accept: application/json y Content-Type: application/json.
  • Mantener la URL de productos; solo cambia el método.

¿Cómo validar la respuesta y parsear el json?

  • Confirmar response.ok antes de leer el cuerpo.
  • En error: throw new Error con el status code.
  • En éxito: await response.json() y devolver el objeto creado.
  • Un POST correcto suele responder 201 y retorna el producto con su ID.

¿Cómo depurar errores comunes en la solicitud?

Al probar en el navegador con el repositorio instanciado, es clave revisar la pestaña Network:

  • Si el payload se envía como objeto de JavaScript, fallará. Debe ir como cadena JSON con JSON.stringify.
  • Si falta Content-Type, el servidor no sabrá qué recibe. Agrega Content-Type: application/json.
  • Un 400 indica petición mal formada o conflicto de datos. Por ejemplo, producto duplicado cuando el título ya existe y genera el mismo slug.
  • Solución rápida: cambiar el título y reintentar. El servidor devolverá el objeto con ID (p.ej., 65 o 66) cuando todo esté bien.

¿Qué diferencias hay entre async/await y then en fetch?

  • fetch es una promesa.
  • Puedes usar async/await dentro del repositorio para claridad.
  • En la capa de UI, puedes encadenar con .then para evitar convertir funciones en asíncronas innecesariamente.

¿Cómo integrar el repositorio en el formulario de creación?

Primero, incluye el script del repositorio en el HTML para tener window.productRepository. Luego, en create.js, el método handleSubmit arma el productData, ajusta el formato y llama al repositorio.

  • images debe ser una lista de strings con las URLs del formulario.
  • price debe ser número.
  • categoryId debe tener el formato esperado por el API.

Ejemplo mínimo en la vista:

// create.js
function handleSubmit(event) {
  event.preventDefault();

  const repository = window.productRepository;

  const productData = {
    title: form.title.value,
    price: Number(form.price.value),
    description: form.description.value,
    categoryId: form.category.value,
    images: [form.imageUrl.value], // lista de strings.
  };

  repository.createProduct(productData)
    .then(json => console.log(json));
}

Habilidades y conceptos aplicados: - Uso del verbo HTTP POST para crear recursos. - Configuración de fetch con method, headers y body. - Serialización con JSON.stringify y consumo con response.json(). - Manejo de errores con response.ok y status code. - Patrón de repositorio para centralizar llamadas al API. - Integración con formularios y depuración con Network en DevTools.

¿Te funcionó la integración y el mapeo de imágenes como lista de strings? Cuéntame en los comentarios cómo te fue y qué mejorarías.