3
\$\begingroup\$

I have tried to make delete functionality with graphQL and php. I am using this library:

https://github.com/webonyx/graphql-php

It has examples, but it does not have mutations example. I tried to create mutation class on my own and it works ok.

The create and update looks ok, but delete looks non standard, but still works. Can you tell is this completely bad or not? And if it is, then how it should look like? Maybe you can give some good tutorial about this.

class MutationType extends ObjectType
{
    protected $serviceManager;

    public function __construct($serviceManager)
    {
        $config = [
            'name' => 'Mutation',
            'fields' => [
                'person' => [
                    'type' => Types::person(),
                    'description' => 'Returns person by id',
                    'args' => [
                        'firstName' => Types::string(),
                        'id' => Type::int(),
                    ]
                ],
                'deletePerson' => [
                    'type' => Types::person(),
                    'args' => [
                        'id' => Type::int(),
                    ]
                ],
            ],
            'resolveField' => function($val, $args, $context, ResolveInfo $info) {
                return $this->{$info->fieldName}($val, $args, $context, $info);
            }
        ];

        $this->serviceManager = $serviceManager ;

        parent::__construct($config);
    }

    public function person($rootValue, $args)
    {

        $personTable = $this->serviceManager->get(PersonTable::class);

        $person = new Person();
        $person->firstName = $args['firstName'];

        if (isset($args['id'])) {
            $person->id = $args['id'];
        }

        return $personTable->savePerson($person);
    }

    public function deletePerson($rootValue, $args)
    {
        $personTable = $this->serviceManager->get(PersonTable::class);


        return $personTable->deletePerson($args['id']);
    }

}

As you can see there is fields array. One item is person, for creating and updating. And another field is deletePerson.

deletePerson has a type, which is not useful. After we delete a person, we do not return person. But it was required key, otherwise I get error.

And here is the part of the code from Zend 2 controller method which uses the mutation type, but you do not need to pay much attention to it I guess:

$queryType = $this->getServiceLocator()->get('Application\GraphQL\Type\QueryType');
            $mutationType = $this->getServiceLocator()->get('Application\GraphQL\Type\MutationType');

            // GraphQL schema to be passed to query executor:
            $schema = new Schema([

                'query' => $queryType,
                'mutation' => $mutationType
            ]);
            $result = GraphQL::execute(
                $schema,
                $data['query'],
                null,
                $appContext,
                (array) $data['variables']
            );
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Consider adding type hint for the $serviceManager parameter passed to constructor. This is obviously a concrete object being passed, so having typeint here and make this class less fragile and prevent the needs to validate the passed parameter (something you are not currently doing).


Why is $config defined in constructor?

Your code is actually improper in that you are overriding the parent constructor inappropriately, with PHP not failing here only because you are not type hinting your parameters. If the parent class gets passed a config as first argument to its constructor, this inheriting class should as well.

You might also consider making a config class that you can pass around.

Ideally your constructor should look like:

public function __construct(Config $config, ServiceManager $serviceManager) {
    $this->serviceManager = $serviceManager;
    parent::__construct($config);
}

You are doing nothing to validate that the parameters passed to your public function are valid for working with. This leads to fragile code that is hard to debug.

Before you do things like make (relatively) expensive database or service calls, you should at least make sure you have viable data passed to work with. Fail early and fail loudly.


Why are you passing $rootValue to your methods when the variable is not even used within the method?

\$\endgroup\$
1
  • \$\begingroup\$ $config defined in constructor because I had such example from that lib github link :) $rootValue passed so that I could access $args variable. If I remove $rootValue, then $args will become $root. But your points I see are about general programming, not specific to graphQL. I wanted to know if I am using graphQL well. E.g is deletePerson field in array good? Or should I do something differently? I made so many mistakes which not related to graphQL to not waste time, that code will not go to production :) \$\endgroup\$
    – Darius.V
    Commented Feb 7, 2017 at 6:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.