How to create a GraphQL Mutation Endpoint for Magento 2.3
Published: 2020-03-18 09:59:57

---
title: How to create a GraphQL Mutation Endpoint for Magento 2.3
published: true
canonical_url: https://larsroettig.dev/how-to-create-a-graph-ql-mutation-endpoint-for-magento-2-3
---

In my last Magento 2 tutorial, I showed how to build a basic GraphQL module with filtering.The primary purpose of GraphQL is to retrieve data (query), but every complete data exchange format needs a way to change server-based data (mutations).Therefore I want to show now how we can change data or create new pickup stores via the frontend.

Currently, the Magento 2 GraphQL Endpoint supports only access controls based on customers. This GraphQL will only allow a queryon the customer data if the customer’s token must proived in the header section.

Since I would like to show only exemplarily how such a thing could look, I did without access control!

Before we can start here, you can find the first module that we need ground for this tutorial.

[How to create a GraphQL Endpoint for Magento 2.3](https://dev.to/larsroettig/how-to-create-a-graphql-endpoint-for-magento-2-3-2520)

[Github Repo](https://github.com/larsroettig/module-graphqlstorepickup/tree/1.0-develop)

Create a new php file `app/code/LarsRoettig/GraphQLStorePickup/Model/Resolver/CreatPickUpStore.php`

This Class holds the logic for that endpoint is responsible for any GraphQL call that creates a new pickup store in the Database.Every Resolver Class is forced to implements `Magento\Framework\GraphQl\Query\ResolverInterface` to work correctly.

```
<?php

declare(strict_types=1);

namespace LarsRoettig\GraphQLStorePickup\Model\Resolver;

use LarsRoettig\GraphQLStorePickup\Model\CreatePickUpStore as CreatPickUpStoreService;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

class CreatPickUpStore implements ResolverInterface
{
    /**
     * @var CreatPickUpStoreService
     */
    private $creatPickUpStore;

    /**
     * @param CreatPickUpStore $creatPickUpStore
     */
    public function __construct(CreatPickUpStoreService $creatPickUpStore)
    {
        $this->creatPickUpStore = $creatPickUpStore;
    }

    /**
     * @inheritDoc
     */
    public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
    {
        if (empty($args['input']) || !is_array($args['input'])) {
            throw new GraphQlInputException(__('"input" value should be specified'));
        }
     
        return ['pick_up_store' => $this->creatPickUpStore->execute($args['input'])];
    }
}
```

File `app/code/LarsRoettig/GraphQLStorePickup/Model/CreatePickUpStore.php`:

The second step is to create a service class that will convert a given array to a pickup store and saves them in the database.A service class help us to have single small bussiness logic that can be used by differnt other php services.

```
<?php
declare(strict_types=1);

namespace LarsRoettig\GraphQLStorePickup\Model;

use LarsRoettig\GraphQLStorePickup\Api\Data\StoreInterface;
use LarsRoettig\GraphQLStorePickup\Api\Data\StoreInterfaceFactory;
use LarsRoettig\GraphQLStorePickup\Api\StoreRepositoryInterface;
use Magento\Framework\Api\DataObjectHelper;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;

class CreatePickUpStore
{

    /**
     * @var DataObjectHelper
     */
    private $dataObjectHelper;
    /**
     * @var StoreRepositoryInterface
     */
    private $storeRepository;
    /**
     * @var StoreInterfaceFactory
     */
    private $storeFactory;

    /**
     * @param DataObjectHelper $dataObjectHelper
     * @param StoreRepositoryInterface $storeRepository
     * @param StoreInterfaceFactory $storeInterfaceFactory
     */
    public function __construct(
        DataObjectHelper $dataObjectHelper,
        StoreRepositoryInterface $storeRepository,
        StoreInterfaceFactory $storeInterfaceFactory
    ) {
        $this->dataObjectHelper = $dataObjectHelper;
        $this->storeRepository = $storeRepository;
        $this->storeFactory = $storeInterfaceFactory;
    }

    /**
     * @param array $data
     * @return StoreInterface
     * @throws GraphQlInputException
     */
    public function execute(array $data): StoreInterface
    {
        try {
            $this->vaildateData($data);
            $store = $this->saveStore($this->createStore($data));
        } catch (\Exception $e) {
            throw new GraphQlInputException(__($e->getMessage()));
        }

        return $store;
    }

    /**
     * Guard function to handle bad request.
     * @param array $data
     * @throws LocalizedException
     */
    private function vaildateData(array $data)
    {
        if (!isset($data[StoreInterface::NAME])) {
            throw new LocalizedException(__('Name must be set'));
        }
    }

    /**
     * Persists the given store in the data base.
     * +
     * @param StoreInterface $store
     * @return StoreInterface
     * @throws CouldNotSaveException
     */
    private function saveStore(StoreInterface $store): StoreInterface
    {
        $this->storeRepository->save($store);

        return $store;
    }

    /**
     * Create a store dto by given data array.
     *
     * @param array $data
     * @return StoreInterface
     * @throws CouldNotSaveException
     */
    private function createStore(array $data): StoreInterface
    {
        /** @var StoreInterface $store */
        $store = $this->storeFactory->create();
        $this->dataObjectHelper->populateWithArray(
            $store,
            $data,
            StoreInterface::class
        );

        return $store;
    }
}

```

File `app/code/LarsRoettig/GraphQLStorePickup/etc/schema.graphqls`

This need to be added to the file:

```
type Mutation {
    createPickUpStores(input: PickUpStoreInput!): PickUpStoreOutput @resolver(class: "\\LarsRoettig\\GraphQLStorePickup\\Model\\Resolver\\CreatPickUpStore") @doc(description: "Create a new pickup store")
}

type PickUpStoreOutput {
    pick_up_store: PickUpStore!
}

input PickUpStoreInput {
    name: String @doc(description: "")
    street: String @doc(description: "")
    street_num: Int @doc(description: "")
    city: String @doc(description: "")
    postcode: String @doc(description: "")
    latitude:Float @doc(description: "")
    longitude: Float @doc(description: "")
}
```

Full File:

```
type Query {
    pickUpStores(
        filter: PickUpStoresFilterInput @doc(description: "")
        pageSize: Int = 5 @doc(description: "How many items should show on the page")
        currentPage: Int = 1 @doc(description: "Allows to ussing paging it start with 1")
    ):PickUpStoresOutput @resolver(class: "\\LarsRoettig\\GraphQLStorePickup\\Model\\Resolver\\PickUpStores") @doc(description: "Allow to query for a pickup store.")
}

type Mutation {
    createPickUpStores(input: PickUpStoreInput!): PickUpStoreOutput @resolver(class: "\\LarsRoettig\\GraphQLStorePickup\\Model\\Resolver\\CreatPickUpStore") @doc(description: "Create a new pickup store")
}

type PickUpStoreOutput {
    pick_up_store: PickUpStore!
}

input PickUpStoreInput {
    name: String @doc(description: "")
    street: String @doc(description: "")
    street_num: Int @doc(description: "")
    city: String @doc(description: "")
    postcode: String @doc(description: "")
    latitude:Float @doc(description: "")
    longitude: Float @doc(description: "")
}

input PickUpStoresFilterInput {
    name: FilterTypeInput @doc(description: "")
    postcode: FilterTypeInput @doc(description: ""),
    street: FilterTypeInput @doc(description: ""),
    street_num: FilterTypeInput @doc(description: ""),
    city: FilterTypeInput @doc(description: ""),
    latitude:FilterTypeInput @doc(description: ""),
    longitude: FilterTypeInput @doc(description: ""),
    or: PickUpStoresFilterInput
}

type PickUpStoresOutput {
    total_count: Int @doc(description: "")
    items: [PickUpStore] @doc(description: "")
}

type PickUpStore {
    entity_id: Int @doc(description: ""),
    name: String @doc(description: ""),
    street: String @doc(description: ""),
    street_num: Int @doc(description: ""),
    city: String @doc(description: ""),
    postcode: String @doc(description: ""),
    latitude:Float @doc(description: ""),
    longitude: Float @doc(description: ""),
}
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#3-installation)3. Installation:

```
bin/magento module:enable LarsRoettig_GraphQLStorePickup
bin/magento setup:db-declaration:generate-whitelist --module-name=LarsRoettig_GraphQLStorePickup
bin/magento setup:upgrade
```

The repo bramch can founded at Github:

[https://github.com/larsroettig/module-graphqlstorepickup/tree/2.0-develop](https://github.com/larsroettig/module-graphqlstorepickup/tree/2.0-develop)

#### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#how-to-call-your-graphql-endpoint)How to call your GraphQL Endpoint

Attention the Url https://your\_domain.test/graphql work only with an valid GraphQL-Request!

<picture>
        <source srcset="https://larsroettig.dev/static/6468c42fd84a9ef9aa58df78b2df2b39/92d98/graphql-playground_mutation.webp 250w,https://larsroettig.dev/static/6468c42fd84a9ef9aa58df78b2df2b39/c0ce8/graphql-playground_mutation.webp 500w,https://larsroettig.dev/static/6468c42fd84a9ef9aa58df78b2df2b39/bc682/graphql-playground_mutation.webp 1000w,https://larsroettig.dev/static/6468c42fd84a9ef9aa58df78b2df2b39/639e8/graphql-playground_mutation.webp 1500w,https://larsroettig.dev/static/6468c42fd84a9ef9aa58df78b2df2b39/09683/graphql-playground_mutation.webp 2000w,https://larsroettig.dev/static/6468c42fd84a9ef9aa58df78b2df2b39/6a3e8/graphql-playground_mutation.webp 2571w" sizes="(max-width: 1000px) 100vw, 1000px" type="image/webp"></source>
        <source srcset="https://larsroettig.dev/static/6468c42fd84a9ef9aa58df78b2df2b39/ef2e0/graphql-playground_mutation.jpg 250w,https://larsroettig.dev/static/6468c42fd84a9ef9aa58df78b2df2b39/66ca5/graphql-playground_mutation.jpg 500w,https://larsroettig.dev/static/6468c42fd84a9ef9aa58df78b2df2b39/aaa41/graphql-playground_mutation.jpg 1000w,https://larsroettig.dev/static/6468c42fd84a9ef9aa58df78b2df2b39/fe044/graphql-playground_mutation.jpg 1500w,https://larsroettig.dev/static/6468c42fd84a9ef9aa58df78b2df2b39/70bbc/graphql-playground_mutation.jpg 2000w,https://larsroettig.dev/static/6468c42fd84a9ef9aa58df78b2df2b39/0ccc1/graphql-playground_mutation.jpg 2571w" sizes="(max-width: 1000px) 100vw, 1000px" type="image/jpeg"></source>
        <img src="https://larsroettig.dev/static/6468c42fd84a9ef9aa58df78b2df2b39/aaa41/graphql-playground_mutation.jpg" alt="GrapQL Mutation" title="GrapQL Mutation Query" loading="lazy" style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0">
      </picture>

**GraphQL-Mutation:**

```
mutation {
  createPickUpStores(
    input: {
      name: "Mustation Store"
      street: "sweswq"
      street_num: 12
      postcode: "83059"
      latitude: 22.3
      longitude:22.3
    }
  )
  {
    pick_up_store {
      name
    }
  }
}
```

(This article was posted to my blog at [https://larsroettig.dev](https://larsroettig.dev). You can [read it online by clicking here](https://larsroettig.dev/how-to-create-a-graph-ql-mutation-endpoint-for-magento-2-3).)