-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request magento-commerce/devdocs#3215 from magento-devdocs…
…/COMDOX-83-migrate-graphql COMDOX-83: Migrate GraphQL Developer Guide from magento/devdocs
- Loading branch information
Showing
222 changed files
with
4,903 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
--- | ||
group: graphql | ||
title: Filtering with custom attributes | ||
migrated_to: https://developer.adobe.com/commerce/webapi/graphql/usage/custom-filters/ | ||
layout: migrated | ||
--- | ||
|
||
As of Magento 2.3.4, the `filter` attribute of the [`products`]({{page.baseurl}}/graphql/queries/products.html) query accepts the `ProductAttributeFilterInput` object. (In previous versions, the `filter` attribute required a `ProductFilterInput` object. This object contained a hard-coded list of filterable attributes, and you could not filter on a custom attribute or any other attribute that was not on the list.) | ||
|
||
## Prerequisites | ||
|
||
You have several options when enabling a custom attribute (or any attribute that is not listed by default in the `ProductAttributeFilterInput` object) for filtering. Navigate to the attribute's **Storefront Properties** page (**Stores** > Attributes > **Product** > <attribute name> > **Storefront Properties**) in the Admin, then perform one or both of the following actions: | ||
|
||
- Set the **Use in Layered Navigation** field to **Filterable (with results)** or **Filterable (no results)**. This field allows the attribute to be used as a filter and returns layered navigation and aggregation data. If this field is set to **No**, then the attribute will not return layered navigation and aggregation data. | ||
|
||
- Set the **Use in Search** and **Visible in Advanced Search** fields to **Yes**. These fields primarily allow Magento to index the attribute's contents, making the data available for quick and advanced searches. Setting both these fields also allows the attribute to be used as a filter. These fields do not configure the presence or absence of layered navigation and aggregation data. If you set only one of these fields to **Yes**, the attribute cannot be used as a filter (unless you set the **Use in Layered Navigation** field to a value other than **No**). | ||
|
||
## Define the filter for your query | ||
|
||
The [`filter`]({{page.baseurl}}/graphql/queries/products.html#ProductFilterInput) definition for your custom attribute requires one of the following input data types: | ||
|
||
- `FilterEqualTypeInput` - Specify this data type when the **Catalog Input Type for Store Owner** field for your custom attribute is set to Yes/No, Select, or Multiple select. Your filter can contain the `eq` or `in` attribute. Use the `eq` attribute to exactly match the specified string. Use the `in` attribute to filter on a comma-separated list of values. | ||
- `FilterMatchTypeInput` - Specify this data type when the **Catalog Input Type for Store Owner** field for your custom attribute is set to Text Field or Text Area. Your filter must contain the `match` attribute, which will return all items that partially fuzzy match the specified string. | ||
- `FilterRangeTypeInput` - Specify this data type when the **Catalog Input Type for Store Owner** field for your custom attribute is set to Price or Date. Your filter can contain one or both of the `to` and `from` attributes, which serve to provide a range of values to filter on. | ||
|
||
## Example | ||
|
||
In this example, the custom attribute `volume` was assigned to the `bags` attribute group. Running the [`customAttributeMetadata` query]({{page.baseurl}}/graphql/queries/custom-attribute-metadata.html) on this custom attribute reveals that the `label` and `value` values for the attribute's options are as follows: | ||
|
||
**Request:** | ||
|
||
```graphql | ||
{ | ||
customAttributeMetadata( | ||
attributes: [ | ||
{ | ||
attribute_code: "volume" | ||
entity_type: "catalog_product" | ||
} | ||
] | ||
) { | ||
items { | ||
attribute_code | ||
attribute_type | ||
entity_type | ||
input_type | ||
attribute_options { | ||
value | ||
label | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
**Response:** | ||
|
||
```graphql | ||
{ | ||
"data": { | ||
"customAttributeMetadata": { | ||
"items": [ | ||
{ | ||
"attribute_code": "volume", | ||
"attribute_type": "Int", | ||
"entity_type": "catalog_product", | ||
"input_type": "select", | ||
"attribute_options": [ | ||
{ | ||
"value": "216", | ||
"label": "Large" | ||
}, | ||
{ | ||
"value": "217", | ||
"label": "Medium" | ||
}, | ||
{ | ||
"value": "218", | ||
"label": "Small" | ||
} | ||
] | ||
} | ||
] | ||
} | ||
} | ||
} | ||
``` | ||
|
||
`label` | `value` | ||
--- | --- | ||
`Large` | `216` | ||
`Medium` | `217` | ||
`Small` | `218` | ||
|
||
In this scenario, a [`products`]({{page.baseurl}}/graphql/queries/products.html) search filtered to return items where the `volume` attribute is set to `Large` would be similar to the following: | ||
|
||
**Request:** | ||
|
||
```graphql | ||
{ | ||
products(filter: { volume: { eq: "216" } }) { | ||
total_count | ||
items { | ||
name | ||
sku | ||
} | ||
} | ||
} | ||
``` | ||
|
||
**Response:** | ||
|
||
The response might be similar to the following: | ||
|
||
```json | ||
{ | ||
"data": { | ||
"products": { | ||
"total_count": 1, | ||
"items": [ | ||
{ | ||
"name": "Wayfarer Messenger Bag", | ||
"sku": "24-MB05" | ||
} | ||
] | ||
} | ||
} | ||
} | ||
``` | ||
|
||
## Output attributes | ||
|
||
When a product requires a filter attribute that is not a field on its output schema, inject the attribute name into the class in a module's `di.xml` file. | ||
|
||
```xml | ||
<type name="Magento\CatalogGraphQl\Model\Resolver\Products\FilterArgument\ProductEntityAttributesForAst" > | ||
<arguments> | ||
<argument name="additionalAttributes" xsi:type="array"> | ||
<item name="field_to_sort" xsi:type="string">field</item> | ||
<item name="other_field_to_sort" xsi:type="string">other_field</item> | ||
</argument> | ||
</arguments> | ||
</type> | ||
``` | ||
|
||
This example adds `field_to_sort` and `other_field_to_sort` attributes to the `additionalAttributes` array defined in the `ProductEntityAttributesForAst` class. The array already contains the `min_price`, `max_price`, and `category_ids` attributes. |
This file was deleted.
Oops, something went wrong.
66 changes: 66 additions & 0 deletions
66
src/guides/v2.4/graphql/develop/create-custom-url-resolver.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
--- | ||
group: graphql | ||
title: Create a custom GraphQL urlResolver service | ||
migrated_to: https://developer.adobe.com/commerce/webapi/graphql/develop/resolvers/ | ||
layout: migrated | ||
--- | ||
|
||
The `Magento\UrlRewrite` module converts URL rewrite requests to canonical URLs. As a result, your custom `urlResolver` module does not require its own class for performing these actions, but it must be able to save and delete entries in the `url_rewrite` table. | ||
|
||
## Create observers | ||
|
||
You can use the `Magento\CmsUrlRewrite\Observer\ProcessUrlRewriteSavingObserver` class as the basis for saving URL rewrites. For deleting entries, create a `ProcessUrlRewriteDeleteObserver` class similar to the following: | ||
|
||
```php | ||
/** | ||
* Generate urls for UrlRewrite and save it in storage | ||
* | ||
* @param \Magento\Framework\Event\Observer $observer | ||
* @return void | ||
*/ | ||
public function execute(EventObserver $observer) | ||
{ | ||
/** @var \Magento\MyModule\Model\Page $myEntityPage */ | ||
$page = $observer->getEvent()->getObject(); | ||
|
||
if ($page->isDeleted()) { | ||
$this->urlPersist->deleteByData( | ||
[ | ||
UrlRewrite::ENTITY_ID => $page->getId(), | ||
UrlRewrite::ENTITY_TYPE => MyEntityPageUrlRewriteGenerator::ENTITY_TYPE, | ||
] | ||
); | ||
} | ||
} | ||
``` | ||
See [Events and observers]({{ page.baseurl }}/extension-dev-guide/events-and-observers.html) for more information about creating an observer. | ||
|
||
## Configure the custom module | ||
|
||
Update the `graphql.xml` and `events.xml` file in your module's `etc` directory to configure your custom GraphQL `urlResolver` service: | ||
|
||
* Add lines similar to the following in your module's `graphql.xml` file to define the enumeration. The `UrlRewriteGraphQl` module defines `UrlRewriteEntityTypeEnum`. | ||
|
||
```xml | ||
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_GraphQl:etc/graphql.xsd"> | ||
<type xsi:type="Enum" name="UrlRewriteEntityTypeEnum"> | ||
<item name="my_entity">MY_ENTITY</item> | ||
</type> | ||
</config> | ||
``` | ||
|
||
* Define two events similar to the following in your module's `events.xml` file. | ||
|
||
```xml | ||
<event name="mymodule_page_save_after"> | ||
<observer name="process_url_rewrite_saving" instance="Magento\MyModuleRewrite\Observer\ProcessUrlRewriteSavingObserver" /> | ||
</event> | ||
<event name="mymodule_page_delete_after"> | ||
<observer name="process_url_rewrite_delete" instance="Magento\MyModuleRewrite\Observer\ProcessUrlRewriteDeleteObserver" /> | ||
</event> | ||
``` | ||
|
||
## Related Topics | ||
|
||
* [Events and observers]({{ page.baseurl }}/extension-dev-guide/events-and-observers.html) | ||
* [urlResolver endpoint]({{ page.baseurl }}/graphql/queries/url-resolver.html) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
--- | ||
group: graphql | ||
title: Debugging GraphQL queries | ||
contributor_name: Atwix | ||
contributor_link: https://www.atwix.com/ | ||
migrated_to: https://developer.adobe.com/commerce/webapi/graphql/develop/debugging/ | ||
layout: migrated | ||
--- | ||
|
||
This topic provides recommendations on how to debug GraphQL requests. | ||
|
||
## Debugging with PHPStorm and Xdebug | ||
|
||
When [using GraphiQL]({{ page.baseurl }}/graphql/index.html#how-to-access-graphql) or any other client for testing GraphQL queries, you might need to debug the request processing. | ||
You can use Xdebug for debugging the PHP execution of a GraphQL query just as you would for other HTTP requests. | ||
To start debugging, add the `?XDEBUG_SESSION_START=PHPSTORM` parameter to the endpoint URL. | ||
The following example shows how to establish a connection between Xdebug and PHPStorm IDE. | ||
|
||
```http | ||
http://<magento2-3-server>/graphql?XDEBUG_SESSION_START=PHPSTORM | ||
``` | ||
|
||
You can also enable an Xdebug connection for a particular request by setting the corresponding header parameter. | ||
|
||
```text | ||
Cookie: XDEBUG_SESSION=PHPSTORM | ||
``` | ||
|
||
As a result, Xdebug within the PHP execution attempts to make a connection to an IDE. If the IDE is listening, it will give the instructions to Xdebug about breakpoints and other relevant information. | ||
|
||
## Related Topics | ||
|
||
* [GraphQL request headers]({{ page.baseurl }}/graphql/send-request.html) | ||
* [Exception handling]({{ page.baseurl }}/graphql/develop/exceptions.html) |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
--- | ||
group: graphql | ||
title: Exception handling | ||
migrated_to: https://developer.adobe.com/commerce/webapi/graphql/develop/exceptions/ | ||
layout: migrated | ||
--- | ||
|
||
The WebApi module has an implementation to "mask" `LocalizedExceptions` so they aren't exposed to the client. GraphQL accomplishes this by restricting verbose output to only those exceptions implementing `\GraphQL\Error\ClientAware`, and only if the system is in developer mode. In these circumstances, Magento returns a full stack trace. Otherwise, Magento writes these exceptions to the system `exception.log` file while returning an "internal server error" to the client. | ||
|
||
You should implement the `\GraphQL\Error\ClientAware` interface to handle errors in your module that are directly related to a GraphQL field having an anticipated exception. If you don't, the client will not receive useful messages. However, you should ensure that you don't implement the `ClientAware` interface for too many exceptions. Doing this risks exposing sensitive data to the client. | ||
|
||
Magento provides the following exception classes in `Magento\Framework\GraphQl\Exception`. | ||
|
||
Class | Exception category | Description | ||
--- | --- | --- | ||
`GraphQlAlreadyExistsException` | `graphql-already-exists` | Thrown when data already exists | ||
`GraphQlAuthenticationException` | `graphql-authentication` | Thrown when an authentication fails | ||
`GraphQlAuthorizationException` | `graphql-authorization` | Thrown when an authorization error occurs | ||
`GraphQlInputException` | `graphql-input` | Thrown when a query contains invalid input | ||
`GraphQlNoSuchEntityException` | `graphql-no-such-entity` | Thrown when an expected resource doesn't exist |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.