webapi.xml Structure
The webapi.xml file defines REST and SOAP API routes for a module.
Basic webapi.xml:
<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
<!-- GET /V1/products/:id -->
<route url="/V1/products/:id" method="GET">
<service class="Magento\Catalog\Api\ProductRepositoryInterface" method="getById"/>
<resources>
<resource ref="Magento_Catalog::products"/>
</resources>
</route>
<!-- POST /V1/products -->
<route url="/V1/products" method="POST">
<service class="Magento\Catalog\Api\ProductRepositoryInterface" method="save"/>
<resources>
<resource ref="Magento_Catalog::products"/>
</resources>
</route>
</routes>
Route attributes:
url— API endpoint path (starts with /V1/)method— HTTP method (GET, POST, PUT, DELETE)service— PHP interface and method to callresources— ACL resource for authorization
URL parameters:
/V1/products/:id → Param :id mapped to method argument
/V1/products/search → No params (uses SearchCriteria)
/V1/orders/:orderId/items/:itemId → Multiple params
HTTP Method Mapping
Each HTTP method maps to a different service interface method.
CRUD mapping:
<!-- GET: Retrieve a single resource -->
<route url="/V1/categories/:categoryId" method="GET">
<service class="Magento\Catalog\Api\CategoryRepositoryInterface" method="get"/>
</route>
<!-- GET (list): Search resources -->
<route url="/V1/categories" method="GET">
<service class="Magento\Catalog\Api\CategoryRepositoryInterface" method="getList"/>
</route>
<!-- POST: Create a new resource -->
<route url="/V1/categories" method="POST">
<service class="Magento\Catalog\Api\CategoryRepositoryInterface" method="save"/>
</route>
<!-- PUT: Update existing resource -->
<route url="/V1/categories/:categoryId" method="PUT">
<service class="Magento\Catalog\Api\CategoryRepositoryInterface" method="save"/>
</route>
<!-- DELETE: Remove resource -->
<route url="/V1/categories/:categoryId" method="DELETE">
<service class="Magento\Catalog\Api\CategoryRepositoryInterface" method="deleteByIdentifier"/>
</route>
Custom endpoints:
<!-- Custom action (non-CRUD) -->
<route url="/V1/products/:productId/links" method="GET">
<service class="Vendor\Module\Api\ProductLinkInterface" method="getLinks"/>
</route>
<!-- Batch operation -->
<route url="/V1/products/bulk" method="POST">
<service class="Magento\Catalog\Api\ProductRepositoryInterface" method="bulkSave"/>
</route>
Method to HTTP verb conventions:
| HTTP Method | Service Method Pattern | Purpose |
|---|---|---|
| GET | get/getById/getList | Retrieve |
| POST | save (new) | Create |
| PUT | save (existing) | Update |
| DELETE | delete/deleteByIdentifier | Remove |
ACL Resources and Authorization
Each API route requires an ACL resource for access control.
ACL resource declaration:
<route url="/V1/products/:id" method="GET">
<service class="Magento\Catalog\Api\ProductRepositoryInterface" method="getById"/>
<resources>
<resource ref="Magento_Catalog::products"/>
</resources>
</route>
Multi-resource routes:
<!-- Requires ALL resources -->
<route url="/V1/orders/:orderId/invoices" method="POST">
<service class="Magento\Sales\Api\InvoiceRepositoryInterface" method="save"/>
<resources>
<resource ref="Magento_Sales::actions_view"/>
<resource ref="Magento_Sales::actions_edit"/>
</resources>
</route>
Anonymous access (no auth):
<route url="/V1/store/storeConfigs" method="GET">
<service class="Magento\Store\Api\StoreConfigManagerInterface" method="getStoreConfigs"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
Self-access:
<!-- User can only access their own resources -->
<route url="/V1/customers/me" method="GET">
<service class="Magento\Customer\Api\CustomerRepositoryInterface" method="get"/>
<resources>
<resource ref="Magento_Customer::manage"/>
</resources>
</route>
ACL resource definitions (acl.xml):
<resource id="Magento_Catalog::products">
<title>Products</title>
<children>
<resource id="Magento_Catalog::products_create" title="Create"/>
<resource id="Magento_Catalog::products_edit" title="Edit"/>
<resource id="Magento_Catalog::products_delete" title="Delete"/>
</children>
</resource>
SOAP vs REST Configuration
Magento supports both REST and SOAP API protocols.
REST endpoints:
GET https://example.com/rest/V1/products
POST https://example.com/rest/V1/products
PUT https://example.com/rest/V1/products/1
DELETE https://example.com/rest/V1/products/1
SOAP endpoints:
https://example.com/soap/V1?wsdl
https://example.com/soap/V1/store=default&wsdl
webapi.xml serves both:
<!-- Same route works for both REST and SOAP -->
<route url="/V1/products/:id" method="GET">
<service class="Magento\Catalog\Api\ProductRepositoryInterface" method="getById"/>
<resources>
<resource ref="Magento_Catalog::products"/>
</resources>
</route>
SOAP-specific considerations:
<!-- SOAP requires complex types for request/response -->
<route url="/V1/products/search" method="GET">
<service class="Magento\Catalog\Api\ProductRepositoryInterface" method="getList"/>
<resources>
<resource ref="Magento_Catalog::products"/>
</resources>
</route>
REST-specific considerations:
- URL parameters mapped to method arguments
- Request body as JSON
- Response as JSON
- Pagination via SearchCriteria query params
Authentication:
# REST with Bearer token
curl -X GET "https://example.com/rest/V1/products/1" \
-H "Authorization: Bearer TOKEN"
# REST with admin token
curl -X POST "https://example.com/rest/V1/integration/admin/token" \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"password"}'
# SOAP with WSSE
# Uses XML Security header with username/password
Route discovery:
# List all API routes
php bin/magento dev:api:list
# Check specific route
grep -r "V1/products" app/code/ vendor/
Quiz
1. What attribute maps a URL parameter to a method argument?
2. What ACL resource allows anonymous API access?
3. Where do REST API routes start in the URL?
4. What is the SOAP endpoint URL format?
Flashcards
Question
What XML file defines API routes?
Click to reveal answer
Answer
webapi.xml
Question
What is the URL prefix for REST API routes?
Click to reveal answer
Answer
/V1/
Question
How do you allow unauthenticated API access?
Click to reveal answer
Answer
Use resource ref="anonymous"
Question
What service method pattern handles GET list requests?
Click to reveal answer
Answer
getList (with SearchCriteria parameter)
Question
What is the SOAP endpoint format?
Click to reveal answer
Answer
/soap/V1?wsdl
Revision Notes
Key Takeaways
- 1. webapi.xml defines REST and SOAP API routes
- 2. URL parameters use : prefix and map to method arguments
- 3. Each route requires ACL resource for authorization
- 4. anonymous resource allows unauthenticated access
- 5. REST uses JSON; SOAP uses XML/WSDL
- 6. GET maps to get/getList, POST to save, DELETE to delete
Interview Tips
- • Explain the difference between REST and SOAP in Magento
- • Describe how ACL resources control API access
- • Know how to create custom API endpoints
- • Discuss SearchCriteria for list endpoints
Cheat Sheet
webapi.xml Cheat Sheet
Route structure:
<route url="/V1/products/:id" method="GET">
<service class="Interface" method="getById"/>
<resources>
<resource ref="Magento_Catalog::products"/>
</resources>
</route>
HTTP Methods:
- GET → get/getById/getList
- POST → save (create)
- PUT → save (update)
- DELETE → delete/deleteByIdentifier
ACL Resources:
- Specific: ref="Magento_Catalog::products"
- Anonymous: ref="anonymous"
URLs:
- REST: /rest/V1/products
- SOAP: /soap/V1?wsdl