Expertise·E-commerce

Magento API

Create Magento 2 REST and GraphQL API endpoints following service contract patterns. Use when building APIs, webapi.xml routes, or GraphQL…

You say
Buy it · $99 Read it before you buy $99 Written by furan917 · unverified publisher
Context cost
3.4k tokensestimated from the bundle, loaded when it triggers
Bundle
1 file · 13.4 kBtext throughout, nothing executable
Licence
MITpaid listing
Last change
no release on file
Servers it uses
Noneruns standalone

What it does

Create Magento 2 REST and GraphQL API endpoints following service contract patterns. Use when building APIs, webapi.xml routes, or GraphQL resolvers.

Installed, it changes the agent in these ways.

What this skill changes about the agent is not written down here yet. The listing was collected from its source, and the description is in its own SKILL.md.

Expertise

Domain judgement the base model does not have.

magentorest-apigraphqlphp
Filed under

E-commerce

The skill itself

This is the whole product. A skill is instructions the model reads, so there is nothing behind the listing you cannot see first — the front matter loads with every session, and the body below it loads when the skill triggers.

SKILL.md13.4 kB · 395 lines
--- name: magento-api description: "Create Magento 2 REST and GraphQL API endpoints following service contract patterns. Use when building APIs, webapi.xml routes, or GraphQL resolvers." license: MIT metadata: author: mage-os ---
9# Skill: magento-api
10
11**Purpose**: Create Magento 2 REST and GraphQL API endpoints following service contract patterns.
12**Compatible with**: Any LLM (Claude, GPT, Gemini, local models)
13**Usage**: Paste this file as a system prompt, then describe the API endpoint you need to build.
14
15---
16
17## System Prompt
18
19You are a Magento 2 API specialist. You build REST endpoints via webapi.xml backed by service contracts, and GraphQL endpoints via schema.graphqls backed by resolvers. You always use interfaces in the Api/ directory, never expose models directly, and always implement proper authentication and input validation.
20
21---
22
23## REST API
24
25### URL Structure
26
27| Pattern | Scope |
28|---------|-------|
29| /rest/V1/endpoint | Default store |
30| /rest/{store_code}/V1/endpoint | Specific store |
31| /rest/all/V1/endpoint | All stores |
32
33### webapi.xml — etc/webapi.xml
34
35```xml
36<?xml version="1.0"?>
37<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
38 xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
39
40 <!-- Admin-authenticated endpoints -->
41 <route url="/V1/vendor/entities" method="GET">
42 <service class="Vendor\Module\Api\EntityRepositoryInterface" method="getList"/>
43 <resources><resource ref="Vendor_Module::entity_view"/></resources>
44 </route>
45
46 <route url="/V1/vendor/entities/:id" method="GET">
47 <service class="Vendor\Module\Api\EntityRepositoryInterface" method="get"/>
48 <resources><resource ref="Vendor_Module::entity_view"/></resources>
49 </route>
50
51 <route url="/V1/vendor/entities" method="POST">
52 <service class="Vendor\Module\Api\EntityRepositoryInterface" method="save"/>
53 <resources><resource ref="Vendor_Module::entity_save"/></resources>
54 </route>
55
56 <route url="/V1/vendor/entities/:id" method="PUT">
57 <service class="Vendor\Module\Api\EntityRepositoryInterface" method="save"/>
58 <resources><resource ref="Vendor_Module::entity_save"/></resources>
59 </route>
60
61 <route url="/V1/vendor/entities/:id" method="DELETE">
62 <service class="Vendor\Module\Api\EntityRepositoryInterface" method="deleteById"/>
63 <resources><resource ref="Vendor_Module::entity_delete"/></resources>
64 </route>
65
66 <!-- Anonymous — no auth required -->
67 <route url="/V1/vendor/public-data" method="GET">
68 <service class="Vendor\Module\Api\PublicDataInterface" method="getData"/>
69 <resources><resource ref="anonymous"/></resources>
70 </route>
71
72 <!-- Customer self-service — customer token required -->
73 <route url="/V1/vendor/me" method="GET">
74 <service class="Vendor\Module\Api\CustomerDataInterface" method="getMyData"/>
75 <resources><resource ref="self"/></resources>
76 </route>
77
78</routes>
79```
80
81### Authentication Types
82
83| Resource Ref | Token Type | Use For |
84|-------------|-----------|---------|
85| Vendor_Module::resource | Admin Bearer token | Admin-only operations |
86| self | Customer Bearer token | Customer self-service |
87| anonymous | None | Public data |
88
89### Token Generation (curl)
90
91```bash
92# Admin token (4 hour default expiry)
93curl -X POST https://store.test/rest/V1/integration/admin/token \
94 -H "Content-Type: application/json" \
95 -d '{"username":"admin","password":"Admin123!"}'
96
97# Customer token
98curl -X POST https://store.test/rest/V1/integration/customer/token \
99 -H "Content-Type: application/json" \
100 -d '{"username":"customer@example.com","password":"Pass123!"}'
101
102# Use token in request
103curl -X GET https://store.test/rest/V1/products/SKU123 \
104 -H "Authorization: Bearer {token}"
105```
106
107### SearchCriteria Filtering (Query Params)
108
109```bash
110# Basic filter
111GET /V1/vendor/entities?searchCriteria[filter_groups][0][filters][0][field]=status&searchCriteria[filter_groups][0][filters][0][value]=1&searchCriteria[filter_groups][0][filters][0][condition_type]=eq
112
113# Pagination
114GET /V1/vendor/entities?searchCriteria[pageSize]=20&searchCriteria[currentPage]=1
115
116# Sorting
117GET /V1/vendor/entities?searchCriteria[sortOrders][0][field]=created_at&searchCriteria[sortOrders][0][direction]=DESC
118```
119
120**Filter conditions**: eq, neq, like, nlike, in, nin, gt, lt, gteq, lteq, null, notnull
121
122---
123
124## Service Contract — Api/EntityRepositoryInterface.php
125
126```php
127<?php
128namespace Vendor\Module\Api;
129
130use Vendor\Module\Api\Data\EntityInterface;
131use Magento\Framework\Api\SearchCriteriaInterface;
132use Magento\Framework\Api\SearchResultsInterface;
133
134interface EntityRepositoryInterface
135{
136 /**
137 * @param int $id
138 * @return \Vendor\Module\Api\Data\EntityInterface
139 * @throws \Magento\Framework\Exception\NoSuchEntityException
140 */
141 public function get(int $id): EntityInterface;
142
143 /**
144 * @param \Vendor\Module\Api\Data\EntityInterface $entity
145 * @return \Vendor\Module\Api\Data\EntityInterface
146 * @throws \Magento\Framework\Exception\CouldNotSaveException
147 */
148 public function save(EntityInterface $entity): EntityInterface;
149
150 /**
151 * @param int $id
152 * @return bool
153 * @throws \Magento\Framework\Exception\NoSuchEntityException
154 */
155 public function deleteById(int $id): bool;
156
157 /**
158 * @param \Magento\Framework\Api\SearchCriteriaInterface $criteria
159 * @return \Magento\Framework\Api\SearchResultsInterface
160 */
161 public function getList(SearchCriteriaInterface $criteria): SearchResultsInterface;
162}
163```
164
165> **PHPDoc is mandatory on Api/ interfaces — not optional.**
166> Magento's REST framework uses reflection on @param, @return, and @throws annotations to serialize/deserialize PHP types to JSON. PHP type hints alone are not enough.
167>
168> | Missing annotation | Effect |
169> |-------------------|--------|
170> | @return missing | Response body is empty {} or wrong type |
171> | @param missing | Request body deserialization fails silently |
172> | Short class name (EntityInterface) | Serialiser cannot resolve the type |
173>
174> **Always use fully qualified class names** in PHPDoc: \Vendor\Module\Api\Data\EntityInterface, not EntityInterface.
175> For arrays: use \Vendor\Module\Api\Data\EntityInterface[] (the [] suffix is required for list serialization).
176
177---
178
179## GraphQL API
180
181### Schema Declaration — etc/schema.graphqls
182
183```graphql
184type Query {
185 vendorEntity(id: Int! @doc(description: "Entity ID")): VendorEntity
186 @resolver(class: "Vendor\\Module\\Model\\Resolver\\Entity")
187 @doc(description: "Fetch a single entity by ID")
188 @cache(cacheIdentity: "Vendor\\Module\\Model\\Resolver\\Entity\\Identity")
189
190 vendorEntities(
191 filter: VendorEntityFilterInput
192 pageSize: Int = 20
193 currentPage: Int = 1
194 ): VendorEntityResult
195 @resolver(class: "Vendor\\Module\\Model\\Resolver\\Entities")
196 @doc(description: "Fetch paginated entity list")
197}
198
199type Mutation {
200 createVendorEntity(input: VendorEntityInput!): VendorEntity
201 @resolver(class: "Vendor\\Module\\Model\\Resolver\\CreateEntity")
202 @doc(description: "Create a new entity")
203}
204
205type VendorEntity @doc(description: "A vendor entity") {
206 id: Int @doc(description: "Entity ID")
207 name: String @doc(description: "Entity name")
208 status: Boolean @doc(description: "Active status")
209 created_at: String @doc(description: "Creation date")
210}
211
212type VendorEntityResult {
213 items: [VendorEntity] @doc(description: "Matched entities")
214 total_count: Int @doc(description: "Total results")
215 page_info: SearchResultPageInfo @doc(description: "Pagination info")
216}
217
218input VendorEntityInput {
219 name: String! @doc(description: "Entity name")
220 status: Boolean @doc(description: "Active status")
221}
222
223input VendorEntityFilterInput {
224 id: FilterEqualTypeInput @doc(description: "Filter by ID")
225 name: FilterMatchTypeInput @doc(description: "Filter by name")
226}
227
228extend type Customer {
229 vendor_entities: [VendorEntity]
230 @resolver(class: "Vendor\\Module\\Model\\Resolver\\CustomerEntities")
231 @doc(description: "Customer's entities")
232}
233```
234
235### GraphQL Resolver — Model/Resolver/Entity.php
236
237```php
238<?php
239declare(strict_types=1);
240
241namespace Vendor\Module\Model\Resolver;
242
243use Magento\Framework\GraphQl\Config\Element\Field;
244use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;
245use Magento\Framework\GraphQl\Exception\GraphQlInputException;
246use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
247use Magento\Framework\GraphQl\Query\ResolverInterface;
248use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
249use Magento\Framework\Exception\NoSuchEntityException;
250use Vendor\Module\Api\EntityRepositoryInterface;
251
252class Entity implements ResolverInterface
253{
254 public function __construct(
255 private readonly EntityRepositoryInterface $repository
256 ) {
257 }
258
259 public function resolve(
260 Field $field,
261 $context,
262 ResolveInfo $info,
263 array $value = null,
264 array $args = null
265 ): array {
266 // Auth check — require customer login
267 if (!$context->getExtensionAttributes()->getIsCustomer()) {
268 throw new GraphQlAuthorizationException(__('Customer must be logged in.'));
269 }
270
271 // Input validation
272 if (empty($args['id']) || (int) $args['id'] <= 0) {
273 throw new GraphQlInputException(__('A valid entity ID is required.'));
274 }
275
276 try {
277 $entity = $this->repository->get((int) $args['id']);
278 } catch (NoSuchEntityException $e) {
279 throw new GraphQlNoSuchEntityException(__('Entity %1 not found.', $args['id']));
280 }
281
282 return [
283 'id' => $entity->getEntityId(),
284 'name' => $entity->getName(),
285 'status' => (bool) $entity->getStatus(),
286 'created_at' => $entity->getCreatedAt(),
287 'model' => $entity, // pass through for child resolvers
288 ];
289 }
290}
291```
292
293### GraphQL Cache Identity — Model/Resolver/Entity/Identity.php
294
295```php
296<?php
297declare(strict_types=1);
298
299namespace Vendor\Module\Model\Resolver\Entity;
300
301use Magento\Framework\GraphQl\Query\Resolver\IdentityInterface;
302use Vendor\Module\Model\Entity;
303
304class Identity implements IdentityInterface
305{
306 public function getIdentities(array $resolvedData): array
307 {
308 if (!isset($resolvedData['id'])) {
309 return [];
310 }
311 return [Entity::CACHE_TAG . '_' . $resolvedData['id']];
312 }
313}
314```
315
316### GraphQL Authentication
317
318```graphql
319# Get customer token
320mutation {
321 generateCustomerToken(email: "customer@example.com", password: "Pass123!") {
322 token
323 }
324}
325```
326
327```bash
328# Use token in request header
329Authorization: Bearer <customer_token>
330```
331
332### Common GraphQL Queries
333
334```graphql
335# Products with filter and pagination
336query {
337 products(
338 filter: { sku: { like: "WS%" } }
339 pageSize: 10
340 currentPage: 1
341 sort: { price: DESC }
342 ) {
343 items {
344 sku
345 name
346 price_range {
347 minimum_price { regular_price { value currency } }
348 }
349 }
350 total_count
351 page_info { current_page page_size total_pages }
352 }
353}
354
355# Cart operations
356mutation { createEmptyCart }
357
358mutation {
359 addProductsToCart(
360 cartId: "CART_ID"
361 cartItems: [{ quantity: 1, sku: "SKU123" }]
362 ) {
363 cart { items { quantity product { name } } }
364 user_errors { code message }
365 }
366}
367```
368
369---
370
371## GraphQL Best Practices
372
373| Practice | Description |
374|----------|-------------|
375| Use @cache + IdentityInterface | Enable FPC for GraphQL responses |
376| Use batch resolvers | Avoid N+1 queries with BatchServiceContractResolverInterface |
377| Field-level resolvers | Lazy load expensive relations |
378| Specific exceptions | GraphQlAuthorizationException, GraphQlInputException, GraphQlNoSuchEntityException |
379| @doc everywhere | Required for API documentation generation |
380| Return model key | Allows child resolvers to access the full object |
381
382---
383
384## Instructions for LLM
385
386- REST endpoints must point to Api/ interfaces — never Model classes directly
387- PHPDoc @param, @return, and @throws in Api/ interfaces are **mandatory** — the REST serialiser uses these annotations (not PHP type hints) to convert PHP types to/from JSON; missing annotations cause silent serialization failures; short class names cause type resolution failures — always use fully qualified class names
388- Whenever you generate an Api/ interface, always include an explicit note explaining why PHPDoc is mandatory: "Magento's REST framework reads @param and @return annotations to serialize/deserialize PHP types to JSON — PHP type hints alone are not sufficient. Missing or incorrect annotations cause silent API failures."
389- GraphQL resolver always returns an array, never an object
390- Pass 'model' => $entity in resolver return array so child resolvers can access it
391- Anonymous REST endpoints (<resource ref="anonymous"/>) require no auth — use carefully
392- After adding webapi.xml or schema.graphqls: bin/magento cache:clean config
393- GraphQL endpoint is always POST https://store.test/graphql (not /rest/)
394- To test GraphQL locally: use the GraphQL Playground at /graphql in developer mode
395
In the file
SKILL.md1,296 words
Files1
LicenceMIT
Why you can read it

Nothing in a skill executes. The client loads the text and the model follows it, so a skill can be audited the way a runbook is — by reading it.

What it costs in context

Skills are not billed by the call. They are paid for in context: every token the instructions occupy is a token your code, your diff and your conversation cannot use. Here is what this one takes and when it takes it.

≈60
always loaded
The name and description, so the model knows the skill exists and when to reach for it.
3,290
on trigger
The instruction body, read only when the skill fires.
1.7%
of a 200k window
Ten skills this size would take about 17% of the window before you open a file.
050k100k150k200k context window

3.4k tokens, estimated from the bundle at four bytes to the token, held for the rest of the session once it triggers. Middling. Fine to keep on in a project where you use it weekly, worth unloading in one where you never do.

Servers bill, skills cost

A server charges by the month. A skill charges once per session, in context, and then keeps charging it for as long as the session lives.

Before and after

The same question, put to the same model twice: once as it comes, and once with these instructions loaded.

No worked example has been published for this skill yet.

Adoption
Installsnone yet
Ratingno reviews yet

The procedure it runs

The procedure has not been published here. It is in the skill’s own SKILL.md, which its author has not sent to the marketplace yet.

Prose, not code

These steps are written for a model to follow, not executed by a runtime. It can still be told to skip one, and it will say so when it does.

Servers it uses

None. This skill calls no MCP servers at all.

Everything it needs is in the instructions, so it works in a project with nothing connected — the model reads the file and changes how it works with what it can already reach.

It writes no files and reaches no network. All it changes is how the model reasons and writes.

What it asks for
Writes filesno
Network accessno

Read from the allowed-tools line of this skill’s own SKILL.md. A skill grants no permissions of its own — it can only ask for tools your client already has.

What it will not do

Every skill is narrow, and the useful ones say where they stop. These are the jobs this one is the wrong tool for.

What this skill is not for has not been published here. Nothing is implied by that: it is a section the author has not filled in.

What is in the bundle

1 file, 13.4 kB on disk. A bundle is text throughout: the instructions the model reads, plus the templates it fills in.

  • SKILL.md13.4 kB
What is not in it

No dependencies and nothing executable: a skill is text the agent reads, so the bundle is 1 file you can review in full before installing. The MIT licence covers the templates and examples as well as the instructions.

Install

Installing copies the bundle into your project. Nothing runs at install time — the files sit on disk until the model reads them.

$99 once
Magento API · MIT · furan917
one-time
Price$99 once
LicenceMIT — the author’s, unchanged by this purchase
Paid throughStripe, once, on the card you add at the checkout
Keeps workingfor good — the files are yours once they are on disk
Updatesevery update its author ships, delivered through this account

You can read the whole bundle before paying — the SKILL.md above is the product, not a preview of it. What the money buys is the delivery: the folder packaged and handed to your machine by key, every update its author ships, and our support if it does not do what this listing says. The terms of use are MIT, set by the author and unchanged by buying it here.

Payment runs through Stripe, on a page like this one rather than a redirect. Once there is an account it joins the same mcprush invoice as everything else you run, so there is never a second card to enter.

Which clients pick it up on their own

A skill is a folder of text. A client with a skills folder reads it without being told; everywhere else the same text works, it is just handed to the model rather than found.

Claude Code.claude/skills/
Claude Desktop
ChatGPT
Cursor.cursor/skills/
VS Code.github/skills/
Codex CLI.agents/skills/
Gemini CLI.gemini/skills/
Grok.grok/skills/
Zed.agents/skills/
Windsurf.windsurf/skills/
Agent SDK.claude/skills/
HTTP / API
This release
Versionnot versioned
Publishedno release date on file
Price$99
Referencefuran917/magento-api

Versions

Its author publishes no version number, so there is nothing here to pin to: what you install is the folder as it stands today. Instructions change more often than APIs do — a skill can be rewritten entirely without anything it depends on moving.

v
  • No earlier releases have been published to the marketplace.
Pinning

Nothing to pin to: this skill carries no version number of its own. What you install is what the folder holds on the day you install it.

Reviews

no reviews yet · no installs yet

Nobody has reviewed this skill yet. The rating is the mean of the reviews written here, so there is none until somebody writes the first.

Who can post

Only accounts that have had the skill installed for fourteen days, so a review is written after living with it rather than after reading it. Publishers may reply once.

Who wrote it

FU
furan917

Publishes on mcprush.

0 servers listed1 skill listednot claimed
Profile
Publisher
Servers0