Extend the data type
Let’s try to extend the GraphQL schema a little so we are able to fetch information about the manufacturer assigned to a product.
Query
query {
product (
id: "dc5ffdf380e15674b56dd562a7cb6aec"
){
title
manufacturer {
id
title
}
}
}
Response
{
"data": {
"product": {
"title": "Kuyichi Ledergürtel JEVER",
"manufacturer": {
"id": "9434afb379a46d6c141de9c9e5b94fcf",
"title": "Kuyichi"
}
}
}
}
Important
As stated in the Specification section, if no manufacturer can be found for the product, we get a null.
We might be tempted to simply extend the product DataType to have a field for the manufacturer id, but please check the hints given in Specification section. The manufacturer should get its own datatype and then get a relation to the product. So let’s add the Manufacturer Data Type:
<?php
declare(strict_types=1);
namespace MyVendor\GraphQL\MyGraph\Manufacturer\DataType;
use OxidEsales\Eshop\Application\Model\Manufacturer as EshopManufacturerModel;
use TheCodingMachine\GraphQLite\Annotations\Field;
use TheCodingMachine\GraphQLite\Annotations\Type;
use TheCodingMachine\GraphQLite\Types\ID;
/**
* @Type()
*/
final class Manufacturer
{
/** @var EshopManufacturerModel */
private $manufacturer;
public function __construct(
EshopManufacturerModel $manufacturer
) {
$this->manufacturer = $manufacturer;
}
/**
* @Field()
*/
public function getId(): ID
{
return new ID($this->manufacturer->getId());
}
/**
* @Field()
*/
public function getTitle(): string
{
return $this->manufacturer->getTitle();
}
}
Also we need the connection to OXID eShop’s OxidEsales\Eshop\Application\Model\Article::getManufacturer()
which
belongs in the infrastructure layer:
<?php
declare(strict_types=1);
namespace MyVendor\GraphQL\MyGraph\Manufacturer\Infrastructure;
use OxidEsales\Eshop\Application\Model\Manufacturer as EshopManufacturerModel;
use MyVendor\GraphQL\MyGraph\Product\DataType\Manufacturer as ManufacturerDataType;
use MyVendor\GraphQL\MyGraph\Product\DataType\Product as ProductDataType;
final class Product
{
public function manufacturerByProduct(ProductDataType $product): ?ManufacturerDataType
{
/** @var null|EshopManufacturerModel $manufacturer */
$manufacturer = $product->getEshopModel()->getManufacturer();
if ($manufacturer === null) {
return null;
}
return new ManufacturerDataType(
$manufacturer
);
}
}
And then we relate it to the product by implementing a RelationService and using the @ExtendType()
notation.
<?php
/**
* Copyright © OXID eSales AG. All rights reserved.
* See LICENSE file for license details.
*/
declare(strict_types=1);
namespace MyVendor\GraphQL\MyGraph\Product\Service;
use MyVendor\GraphQL\MyGraph\Product\DataType\Manufacturer;
use MyVendor\GraphQL\MyGraph\Product\DataType\Product;
use MyVendor\GraphQL\MyGraph\Product\Infrastructure\Product as ProductInfrastructure;
use TheCodingMachine\GraphQLite\Annotations\ExtendType;
use TheCodingMachine\GraphQLite\Annotations\Field;
/**
* @ExtendType(class=Product::class)
*/
final class RelationService
{
/** @var ProductInfrastructure */
private $productInfrastructure;
public function __construct(
ProductInfrastructure $productInfrastructure
) {
$this->productInfrastructure = $productInfrastructure;
}
/**
* @Field()
*/
public function manufacturer(Product $product): ?Manufacturer
{
return $this->productInfrastructure
->manufacturerByProduct($product);
}
}
Please remember as this is a new type for GraphQL, it needs to be
registered in the NamespaceMapper::getTypeNamespaceMapping()
method!
At this point, running our extended query will be possible.