In this post, I’m continuing the story of building a GraphQL server for my Resource Allocation system. Here are the first and second parts of the series.

Now that we can execute the queries we’ll need to get started, we need to implement GraphQL mutations which will let us enter and update data. The first of these will be addProjectMutation.

To implement this we’ll define the class App\GraphQL\Mutation\AddProjectMution as follows:

 <?PHP
namespace App\GraphQL\Mutation;
use GraphQL;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Mutation;
use App\Project;

class AddProjectMutation extends Mutation
{
    protected $attributes = [
        'name' => 'addProjectMutation'
    ];

    public function type() {
        return GraphQL::type('Project');
    }

    public function args() {
        return [
            'name' => ['name' => 'name', 'type' => Type::string()],
            'technology' => ['name' => 'technology', 'type' => Type::string()],
        ];
    }

    public function resolve($root, $args) {
        $project = new Project();
        $project->name = $args['name'];
        $project->technology = $args['technology'];
        $project->save();
        return $project;
    }
}

The mutations we create must be declared in the schema summary we’ve been building in config/graphql.php along with the queries:

'mutation' => [
                'addProjectMutation' => 'App\GraphQL\Mutation\AddProjectMutation',
],

Special note: using mutations is the first place in our build where we will use input variables in our GraphQL queries. The default parameter name for the input variable in \Folklore\GraphQL is “params”. However, all of the graphiql implementations I’ve seen use “variables” as the parameter name, so let’s change that in config/graphql.php while we are declaring our mutation.

'variables_input_name' => 'variables',

Now we are ready to give our new mutation a try:

We can carry on in the same way with the other mutations we will need: addResourceMutation, updateAllocationMutation and updateResourceMutation. I’ll leave a link to the source repository for the required classes and updated configuration, and include usage examples here:

This is the code to support the updateResourceMutation…

<?PHP
namespace App\GraphQL\Mutation;
use GraphQL;
use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Mutation;
use App\Resource;

class UpdateResourceMutation extends Mutation
{
    protected $attributes = [
        'name' => 'updateResourceMutation'
    ];

    public function type() {
        return GraphQL::type('Resource');
    }

    public function args() {
        return [
            'id' => ['name' => 'id', 'type' => Type::nonNull(Type::string())],
            'name' => ['name' => 'name', 'type' => Type::string()],
            'title' => ['name' => 'title', 'type' => Type::string()],
        ];
    }

    public function resolve($root, $args)
    {
        $resource = Resource::find($args['id']);
        if (!$resource) {
            return null;
        }
        $resource->name = $args['name'];
        $resource->title = $args['title'];
        $resource->save();
        return $resource;
    }
}

…and here I am updating the resource I created above:

The last example is for updateAllocationMutation. I didn’t create an addAllocationMutation or deleteAllocationMutation; instead I plan to create an allocation if I need one and it didn’t exist before, and edit it if it exists. The resolve function of this mutation looks like this:

    public function resolve($root, $args) {
        $allocation = Allocation::where("project_id", $args['project_id'])
            ->where("resource_id", $args['resource_id'])
            ->where("startdate", $args['startdate'])
            ->first();
        if (!$allocation) {
            $allocation = new Allocation();
            $allocation->project_id = $args['project_id'];
            $allocation->resource_id = $args['resource_id'];
            $allocation->startdate = $args['startdate'];
        }
        $allocation->note = $args['note'];
        $allocation->hours = $args['hours'] ? $args['hours'] : 0;
        $allocation->save();
        return $allocation;
    }

To create the allocations, I’ll use the id of of a project, the id of a resource, and the first date of the week in question (always a Monday).

With this set of GraphQL queries and mutations implemented, I can now start on the React application — in the next post in this series.