This guide explains how to access the Merchi REST API using the provided TypeScript methods and demonstrates how to perform Create, Read, Update, and Delete (CRUD) operations on a Product entity.


1. Overview

Merchi provides a REST API for managing various resources like products, jobs, and invoices. This guide focuses on the Product entity and demonstrates how to interact with it using provided helper methods and authentication.


2. Prerequisites

Authentication

Base URL


3. Initialization

Set up API Client

Ensure the API client is properly initialized with tokens.

import { Merchi } from "merchi_sdk_ts";
const merchi = new Merchi("your-session-token");

4. Understand REST API URL Structure

A REST API URL typically follows this format:

<base_url>/<version>/<resource>?<query_parameters>

Components


5. Build REST API URL Dynamically

In TypeScript, you can construct API URLs dynamically using the URL object:

function buildApiUrl(baseUrl: string, entityName: string, resourceId?: string, queryParams?: Record<string, string>): string {
  const url = new URL(`${baseUrl}/${entityName}${entityId ? `/${entityId}` : ''}`);
  if (queryParams) {
    Object.entries(queryParams).forEach(([key, value]) => url.searchParams.append(key, value));
  }
  return url.toString();
}

// Example Usage:
const apiUrl = buildApiUrl(
  "https://api.example.com",
  "products",
  "123",
  { embed: "categories", includeArchived: "true" }
);
console.log(apiUrl); // Output: https://api.example.com/products/123?embed=categories&includeArchived=true

6. Use fetch for HTTP Requests

The fetch function is used to perform HTTP operations such as GET, POST, PUT, and DELETE.

6.1 Common fetch Template

async function apiFetch<T>(url: string, options?: RequestInit): Promise<T> {
  const response = await fetch(url, options);
  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Error: ${response.status} - ${error.message}`);
  }
  return response.json();
}

6.2 HTTP Methods for CRUD

A. Create (POST)

Create a new resource by sending data in the request body.

async function createProduct(baseUrl: string, product: Record<string, any>) {
  const url = buildApiUrl(baseUrl, "products");
  const options: RequestInit = {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(product),
  };
  return apiFetch(url, options);
}

// Usage
createProduct("https://api.example.com", { name: "New Product", price: 100 })
  .then((data) => console.log("Created Product:", data))
  .catch((err) => console.error(err));

B. Read (GET)

Retrieve a resource by its ID or fetch a list of resources.

async function getProduct(baseUrl: string, productId: string) {
  const url = buildApiUrl(baseUrl, "products", productId);
  return apiFetch(url);
}

// Usage
getProduct("https://api.example.com", "123")
  .then((data) => console.log("Fetched Product:", data))
  .catch((err) => console.error(err));

C. Update (PUT or PATCH)

Update an existing resource by sending modified data.

async function updateProduct(baseUrl: string, productId: string, updatedData: Record<string, any>) {
  const url = buildApiUrl(baseUrl, "products", productId);
  const options: RequestInit = {
    method: "PUT",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(updatedData),
  };
  return apiFetch(url, options);
}

// Usage
updateProduct("https://api.example.com", "123", { price: 150 })
  .then((data) => console.log("Updated Product:", data))
  .catch((err) => console.error(err));

D. Delete (DELETE)

Delete a resource by its ID.

async function deleteProduct(baseUrl: string, productId: string) {
  const url = buildApiUrl(baseUrl, "products", productId);
  const options: RequestInit = { method: "DELETE" };
  return apiFetch(url, options);
}

// Usage
deleteProduct("https://api.example.com", "123")
  .then(() => console.log("Product Deleted"))
  .catch((err) => console.error(err));

7. Best Practices

7.1 Use try...catch for Error Handling

Always wrap your API calls in a try...catch block to handle errors gracefully.

async function safeApiCall() {
  try {
    const product = await getProduct("https://api.example.com", "123");
    console.log("Product:", product);
  } catch (error) {
    console.error("Error occurred:", error);
  }
}

7.2 Centralize Configuration

Centralize the base URL and headers for maintainability.

const config = {
  baseUrl: "https://api.example.com",
  headers: { "Content-Type": "application/json" },
};

function getApiHeaders() {
  return { ...config.headers, Authorization: "Bearer your-token" };
}