webapi.xml Structure
Basic webapi.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
<router url="/V1">
<route url="/custom" method="get">
<service class="Vendor\Module\Api\CustomInterface" method="getItems"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
</router>
</config>
Route Elements
| Element | Description |
|---|---|
<router> |
Base URL prefix |
<route> |
Individual route definition |
<service> |
Service contract class and method |
<resources> |
ACL resource permissions |
File Location
app/code/Vendor/Module/etc/webapi.xml
Route Attributes
<route url="/items/:id" method="get">
<!-- URL: /V1/items/{id} -->
<service class="Vendor\Module\Api\ItemInterface" method="getById"/>
<resources>
<resource ref="Vendor_Module::items"/>
</resources>
</route>
URL Patterns
Basic Patterns
<!-- Simple route -->
<route url="/items" method="get">
<!-- GET /V1/items -->
</route>
<!-- Route with parameter -->
<route url="/items/:id" method="get">
<!-- GET /V1/items/123 -->
</route>
<!-- Nested route -->
<route url="/customers/:customerId/orders" method="get">
<!-- GET /V1/customers/456/orders -->
</route>
URL Parameters
<!-- Single parameter -->
<route url="/items/:id" method="get">
<!-- :id maps to method parameter -->
</route>
<!-- Multiple parameters -->
<route url="/items/:itemId/reviews/:reviewId" method="get">
<!-- :itemId and :reviewId -->
</route>
<!-- Optional parameter (regex) -->
<route url="/items/:id[/:option]" method="get">
<!-- :option is optional -->
</route>
HTTP Methods in URLs
<!-- GET route -->
<route url="/items" method="get">
<!-- POST route -->
<route url="/items" method="post">
<!-- PUT route -->
<route url="/items/:id" method="put">
<!-- DELETE route -->
<route url="/items/:id" method="delete">
<!-- PATCH route -->
<route url="/items/:id" method="patch">
Route Parameters
Parameter Mapping
<route url="/items/:id" method="get">
<service class="Vendor\Module\Api\ItemInterface" method="getById"/>
</route>
// Service interface
interface ItemInterface
{
/**
* @param int $id
* @return ItemDataInterface
*/
public function getById(int $id): ItemDataInterface;
}
The :id in URL maps to $id parameter in method.
Multiple Parameters
<route url="/customers/:customerId/orders/:orderId" method="get">
<service class="Vendor\Module\Api\OrderInterface" method="getByCustomerAndOrder"/>
</route>
interface OrderInterface
{
/**
* @param int $customerId
* @param int $orderId
* @return OrderDataInterface
*/
public function getByCustomerAndOrder(int $customerId, int $orderId): OrderDataInterface;
}
Query Parameters
# Query parameters are automatically available
GET /V1/items?page=1&limit=10&sort=name
// Access via request
public function getItems(): array
{
$request = $this->request;
$page = $request->getParam('page', 1);
$limit = $request->getParam('limit', 10);
}
Wildcard Routes
Catch-All Routes
<!-- Catch-all for custom routes -->
<route url="/custom/:param1/:param2" method="get">
<service class="Vendor\Module\Api\CustomInterface" method="handleRoute"/>
</route>
Dynamic Route Segments
<!-- Multiple dynamic segments -->
<route url="/api/:version/:resource/:id" method="get">
<service class="Vendor\Module\Api\DynamicInterface" method="handleRequest"/>
</route>
Route Priority
<!-- More specific routes first -->
<router url="/V1">
<!-- Specific route -->
<route url="/items/special" method="get">
<service class="Vendor\Module\Api\SpecialInterface" method="getSpecial"/>
</route>
<!-- General route (catches /items/anything) -->
<route url="/items/:id" method="get">
<service class="Vendor\Module\Api\ItemInterface" method="getById"/>
</route>
</router>
Complete Example
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
<router url="/V1">
<!-- GET /V1/vendor/items -->
<route url="/vendor/items" method="get">
<service class="Vendor\Module\Api\ItemInterface" method="getList"/>
<resources>
<resource ref="Vendor_Module::items_list"/>
</resources>
</route>
<!-- GET /V1/vendor/items/123 -->
<route url="/vendor/items/:id" method="get">
<service class="Vendor\Module\Api\ItemInterface" method="getById"/>
<resources>
<resource ref="Vendor_Module::items_view"/>
</resources>
</route>
<!-- POST /V1/vendor/items -->
<route url="/vendor/items" method="post">
<service class="Vendor\Module\Api\ItemInterface" method="create"/>
<resources>
<resource ref="Vendor_Module::items_create"/>
</resources>
</route>
<!-- PUT /V1/vendor/items/123 -->
<route url="/vendor/items/:id" method="put">
<service class="Vendor\Module\Api\ItemInterface" method="update"/>
<resources>
<resource ref="Vendor_Module::items_edit"/>
</resources>
</route>
<!-- DELETE /V1/vendor/items/123 -->
<route url="/vendor/items/:id" method="delete">
<service class="Vendor\Module\Api\ItemInterface" method="delete"/>
<resources>
<resource ref="Vendor_Module::items_delete"/>
</resources>
</route>
</router>
</config>
Quiz
1. Where is webapi.xml located?
2. How do you define a route parameter?
3. What maps routes to PHP methods?
Flashcards
Question
Where is webapi.xml located?
Click to reveal answer
Answer
app/code/Vendor/Module/etc/webapi.xml
Question
How do you define route parameters?
Click to reveal answer
Answer
Use :paramName in URL
Question
What element maps to PHP methods?
Click to reveal answer
Answer
service class and method
Question
How do you define HTTP methods?
Click to reveal answer
Answer
method attribute: get, post, put, delete
Question
How do you restrict access?
Click to reveal answer
Answer
Use resources with ACL ref
Revision Notes
Key Takeaways
- 1. webapi.xml defines REST routes
- 2. URL parameters use :paramName syntax
- 3. Service element maps to PHP interface methods
- 4. Resources control ACL permissions
- 5. Routes support all HTTP methods
Interview Tips
- • Explain webapi.xml structure
- • Know how to define route parameters
- • Discuss mapping routes to service contracts
- • Be ready to create custom routes
Cheat Sheet
webapi.xml:
<route url="/items/:id" method="get">
<service class="Vendor\Api\Interface" method="getById"/>
<resources>
<resource ref="Vendor::items"/>
</resources>
</route>
URL: /V1/items/123
Method: get
Service: Interface::getById(123)