Skip to content
intermediate Phase 31 · Admin & System XML

webapi.xml Deep Dive

REST resource paths, method mapping, ACL resources, and SOAP vs REST configuration.

45m
0 problems
Topic Progress 0%

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 call
  • resources — 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?

Question 1 options

2. What ACL resource allows anonymous API access?

Question 2 options

3. Where do REST API routes start in the URL?

Question 3 options

4. What is the SOAP endpoint URL format?

Question 4 options

Flashcards

Question

What XML file defines API routes?

Answer

webapi.xml

Question

What is the URL prefix for REST API routes?

Answer

/V1/

Question

How do you allow unauthenticated API access?

Answer

Use resource ref="anonymous"

Question

What service method pattern handles GET list requests?

Answer

getList (with SearchCriteria parameter)

Question

What is the SOAP endpoint format?

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