Skip to content
This repository has been archived by the owner on Feb 10, 2019. It is now read-only.

Update to latest version of graphql-php #330

Open
spawnia opened this issue Apr 25, 2018 · 1 comment
Open

Update to latest version of graphql-php #330

spawnia opened this issue Apr 25, 2018 · 1 comment

Comments

@spawnia
Copy link

spawnia commented Apr 25, 2018

Hi, i have been using your package for a bit now - it is great, thank you!

I have been having issues with the type coercion of the built-in scalar types of graphql-php. After some investigation, i found that the issue has been fixed in the upstream library.

From version 0.11 going forward, they have added more strict input type coercion for scalars - a feature which i desperately require. Do you have plans to update to a newer version? If so, can i assist with that?

@spawnia
Copy link
Author

spawnia commented Apr 26, 2018

The issue with the current scalar types is that they cover up errors. For example, the rule to
check if an input field is a boolean does not work in most cases:

<?php

namespace App\GraphQL\Types;

use GraphQL\Type\Definition\Type;
use Folklore\GraphQL\Support\Type as BaseType;

class TestType extends BaseType
{
    protected $attributes = [
        'name' => 'Test',
        'description' => 'A type',
    ];
    
    public function fields()
    {
        return [
            'result' => [
                'type' => Type::boolean(),
            ],
        ];
    }
}
<?php

namespace App\GraphQL\Mutations;

use Folklore\GraphQL\Support\Mutation;
use GraphQL;
use GraphQL\Type\Definition\Type;

class TestMutation extends Mutation
{
    public function type()
    {
        return GraphQL::type('Test');
    }
    
    public function args()
    {
        return [
            'input' => [
                'type' => Type::boolean(),
                'rules' => 'boolean'
            ],
        ];
    }
    
    public function resolve($root, $args)
    {
        return ['result' => $args['input']];
    }
}

The behaviour differs depending on how input is passed.

If it is written inline as part of the query, it is validated through the Schema Definition and never even gets to the Laravel Validation.

If it is passed as a variable, the value is coerced in BooleanType->parseValue() and gets
converted to a boolean - this leads to some weird results.

Consider the following query:

mutation test($input: Boolean) {
  test(input: $input) {
    result
  }
}

The following shows the current behaviour:

Truthy:

{
  "input": true
}
OR
{
  "input": 1
}
OR
{
  "input": "false"
}
OR
{
  "input": 123
}
OR
{
  "input": -1
}
OR
{
  "input": {
    "foo": "bar"
  }
}
OR
{
  "input": [{}]
}
OR
{
  "input": [false]
}

Output
{
  "data": {
    "test": {
      "result": true
    }
  }
}

Falsy:

{
  "input": false
}
OR
{
  "input": {}
}
OR
{
  "input": "0"
}
OR
{
  "input": []
}

Output
{
  "data": {
    "test": {
      "result": false
    }
  }
}

This passes through to Laravel and gets caught there:

{
  "input": ""
}
OR
{
  "input": null
}

Output:
{
  "data": {
    "test": null
  },
  "errors": [
    {
      "message": "validation",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "validation": {
        "input": [
          "The input field must be true or false."
        ]
      }
    }
  ]
}

For completeness sake, if variables are left blank:

{
  "data": {
    "test": null
  },
  "errors": [
    {
      "message": "Undefined index: input",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ]
    }
  ]
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant