This tutorial explains how to implement a ResolverInterface
using the example of accessing the available currencies at the store and the current currency code(How to work with resolvers?).
<aside>
✅ In fact, this is what happens in ScandiPWA CurrencyResolver, which is used in the currencyData
query. For this reason, the tutorial query name will be simply currency
.
</aside>
Let's say you want to make a request with the fields current_currency_code
and available_currencies_data
. Here is an example query:
query {
currency {
current_currency_code
available_currencies_data {
id
label
value
}
}
}
This is a good example of using the ResolverInterface
because it involves a simple query that is not a part of an entity returned in bulk. (What interface should I implement?)
<aside>
✅ This tutorial utilizes a module Currency
located in the Scandiweb
vendor, but you can name it whatever you prefer. (how to create a module?)
</aside>
To implement a ResolverInterface
you need to:
<aside> ⚠️ To make these changes available, you need to flush the cache. If you're using CMA, run:
npm run cli
magento cache:flush
</aside>
When defining the query or mutation in the schema, you should consider what should be the input and output. In the example query from the beginning, it’s not necessary to use any input, and the output should include the fields current_currency_code
and available_currencies_data
.
The current_currency_code
is a simple string, but available_currencies_data
needs to be a list of arrays that match the defined Currency
type. This type includes id
, label
, and value
.
Create a file in your module src/etc/schema.graphqls
. In this example, this file should look like this:
type Query {
currency: CurrencyConfig @resolver(class: "Scandiweb\\\\Currency\\\\Model\\\\Resolver\\\\Currency\\\\TutorialCurrencyResolver") @doc(description: "The currency data query")
}
type CurrencyConfig {
available_currencies_data: [Currency],
current_currency_code: String
}
type Currency {
id: String
label: String
value: String
}
Note that the currency
query should be resolved by the TutorialCurrencyResolver
. This resolver will be created in the next step.
To create the resolver responsible for resolving the query, pay attention to the location it is defined in the schema. It’s a good practice to define resolvers in the <VENDOR>/<MODULE>/Model/Resolver/
folder. But in this case, it also was included in the Currency
folder (How to work with resolvers?).
Create a PHP class in the specified folder that implements ResolverInterface
, you must also include the resolve
method:
<?php
declare(strict_types=1);
//vv don't forget to update the namespace
namespace Scandiweb\\Currency\\Model\\Resolver\\Currency;
use Magento\\Framework\\GraphQl\\Config\\Element\\Field;
use Magento\\Framework\\GraphQl\\Query\\ResolverInterface;
use Magento\\Framework\\GraphQl\\Schema\\Type\\ResolveInfo;
/**
* Currency resolver, used for GraphQL request processing.
*/
class TutorialCurrencyResolver implements ResolverInterface
{
/**
* @inheritdoc
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
) {
return [
'current_currency_code' => 'USD',
'available_currencies_data' => [
[
'id' => '1',
'label' => 'USD',
'value' => 'USD'
],
[
'id' => '2',
'label' => 'BRL',
'value' => 'BRL'
]
]
];
}
}
This resolve method should return data according to the definition in the schema (What data should a resolver return?). In this code it returns data directly(fake data), making it easy for you to test if everything is working properly so far.
<aside>
⚠️ To make your changes available, you need to flush the Magento cache. In CMA this is easily done in the CLI using the magento cache:flush
command.
</aside>
Once you have defined the basic resolver class, you should include the logic to process the request and return the correct data.
Both current_currency_code
and available_currencies_data
can be accessed using the store manager, but their logic is different:
<?php
declare(strict_types=1);
//vv don't forget to update the namespace
namespace Scandiweb\\Currency\\Model\\Resolver\\Currency;
use Magento\\Framework\\Exception\\NoSuchEntityException;
use Magento\\Framework\\GraphQl\\Config\\Element\\Field;
use Magento\\Framework\\GraphQl\\Query\\ResolverInterface;
use Magento\\Framework\\GraphQl\\Schema\\Type\\ResolveInfo;
use Magento\\Store\\Model\\StoreManagerInterface;
/**
* Currency resolver, used for GraphQL request processing.
*/
class TutorialCurrencyResolver implements ResolverInterface
{
/**
* @var StoreManagerInterface
*/
protected $storeManager;
/**
* @param StoreManagerInterface $storeManager
*/
public function __construct(
StoreManagerInterface $storeManager
) {
$this->storeManager = $storeManager;
}
/**
* @inheritdoc
*/
public function resolve(
Field $field,
$context,
ResolveInfo $info,
array $value = null,
array $args = null
) {
return [
'available_currencies_data' => $this->getCurrenciesData(),
'current_currency_code' => $this->storeManager->getStore()->getCurrentCurrency()->getCode()
];
}
/**
* @return array
* @throws NoSuchEntityException
*/
public function getCurrenciesData() {
$availableCurrenciesCodes = $this->storeManager->getStore()->getAvailableCurrencyCodes();
$currencyData = [];
foreach ($availableCurrenciesCodes as $currencyCode) {
$currencyData[] = [
'id' => $currencyCode,
'label' => $currencyCode,
'value' => $currencyCode
];
}
return $currencyData;
}
}
Now everything is correct, and you can make a GraphQL request using the query at the beginning to test.
<aside>
⚠️ To make your changes available, you need to flush the Magento cache. In CMA this is easily done in the CLI using the magento cache:flush
command.
</aside>