Setting Up Magento 2 REST/GraphQL API
Magento 2 has a powerful API out of the box. REST API covers all entities: products, orders, customers, shopping carts. GraphQL API (Magento 2.3+) is for frontend and PWA. Both require authentication configuration and understanding of resource structure.
REST API: Authentication
Token-based (client/user):
# Get admin token
curl -X POST https://shop.com/rest/V1/integration/admin/token \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "admin_pass"}'
# Response: "abc123token..."
# Get customer token
curl -X POST https://shop.com/rest/V1/integration/customer/token \
-H "Content-Type: application/json" \
-d '{"username": "[email protected]", "password": "pass"}'
OAuth 1.0a (for integrations): Store → System → Integrations → Add New Integration → Resource Access: select required resources → get Consumer Key/Secret, Access Token/Secret.
REST API: Working with Products
# Get list of products with filtering
curl -X GET "https://shop.com/rest/V1/products?searchCriteria[filter_groups][0][filters][0][field]=price&searchCriteria[filter_groups][0][filters][0][value]=100&searchCriteria[filter_groups][0][filters][0][condition_type]=gt&searchCriteria[pageSize]=20" \
-H "Authorization: Bearer ADMIN_TOKEN"
# Create product
curl -X POST https://shop.com/rest/V1/products \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"product": {
"sku": "LAPTOP-001",
"name": "Laptop 15",
"price": 75000,
"status": 1,
"type_id": "simple",
"attribute_set_id": 4,
"custom_attributes": [
{"attribute_code": "description", "value": "<p>Description</p>"},
{"attribute_code": "short_description", "value": "Short description"}
]
}
}'
# Update stock
curl -X PUT "https://shop.com/rest/V1/products/LAPTOP-001/stockItems/1" \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"stockItem": {"qty": 50, "is_in_stock": true}}'
REST API: Orders
# List orders
curl "https://shop.com/rest/V1/orders?searchCriteria[filter_groups][0][filters][0][field]=status&searchCriteria[filter_groups][0][filters][0][value]=pending" \
-H "Authorization: Bearer ADMIN_TOKEN"
# Change order status
curl -X POST "https://shop.com/rest/V1/orders/123/comments" \
-H "Authorization: Bearer ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"statusHistory": {"comment": "Order shipped", "is_customer_notified": 1, "is_visible_on_front": 1, "status": "complete"}}'
GraphQL API
Magento 2 GraphQL API is optimized for PWA/headless frontends:
# Product search
query SearchProducts($search: String!, $pageSize: Int) {
products(search: $search, pageSize: $pageSize) {
total_count
items {
id
sku
name
price_range {
minimum_price {
regular_price { value currency }
final_price { value currency }
}
}
image { url label }
... on ConfigurableProduct {
configurable_options {
label
values { label value_index }
}
}
}
}
}
# Shopping cart
mutation CreateCart {
createGuestCart
}
mutation AddToCart($cartId: String!, $sku: String!, $qty: Float!) {
addSimpleProductsToCart(input: {
cart_id: $cartId
cart_items: [{
data: { sku: $sku, quantity: $qty }
}]
}) {
cart {
items { id quantity product { sku name } prices { price { value } } }
prices { grand_total { value currency } }
}
}
}
Custom REST API Module
// Api/ProductStatsInterface.php
interface ProductStatsInterface {
public function getStats(string $sku): array;
}
// registration.php + module.xml ...
// Model/ProductStats.php
class ProductStats implements ProductStatsInterface {
public function __construct(
private readonly ProductRepositoryInterface $productRepository,
private readonly StockRegistryInterface $stockRegistry
) {}
public function getStats(string $sku): array {
$product = $this->productRepository->get($sku);
$stock = $this->stockRegistry->getStockItemBySku($sku);
return [
'sku' => $sku,
'name' => $product->getName(),
'price' => $product->getFinalPrice(),
'qty' => $stock->getQty(),
'in_stock' => $stock->getIsInStock(),
];
}
}
// etc/webapi.xml
// <route url="/V1/products/:sku/stats" method="GET">
// <service class="Vendor\Module\Api\ProductStatsInterface" method="getStats"/>
// <resources><resource ref="Magento_Catalog::products"/></resources>
// </route>
Rate Limiting and Performance
Magento REST API without cache puts load on server. Recommendations:
- Enable Varnish before Magento (Full Page Cache)
- For public endpoints — Nginx cache at location level
- Use Async REST API (POST
/async/V1/products) for bulk updates
Timeline
Setting up OAuth integration + 5–10 REST endpoints — 5–7 days. Developing a custom GraphQL module — additional 3–5 days.







