PHPでGraphQLを試したい

まずubuntuにcomposerを入れます。

$ curl -sS https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer
$ sudo chmod +x /usr/local/bin/composer
$ source ~/.bashrc
$ composer -v
Composer version 2.1.8 2021-09-15 13:55:14

### ライブラリのインストール
$ composer require webonyx/graphql-php

public/graphql/index.php

require_once __DIR__ . '/../../vendor/autoload.php';

use GraphQL\Type\Definition\ObjectType;

class Query extends ObjectType {
	public function __contruct(){
		parent::__construct([
			'name' => 'Query',
			'fields' => [
				'number' => [
					'type' => Type::int(),
					'args' => [
						'number' => Type::int(),
					],
					'resolve' => function($value, $args, $context, ResolveInfo $resolveInfo){
						return $args['number'];
					}
				],
			],
		]);
	}
}

$schema = new GraphQL\Type\Schema([
	'query' => new Query(),
]);

$server = new Graph\Server\StandardServer([
	'schema' => $schema
]);

$ php -S 192.168.34.10:8000
$ curl -X POST -H “Content-Type: application/json” “http://192.168.34.10:8000/graphql/” \
> -d ‘{“query”: “query { number(number: 20210928) }”}’

### Repositoryを使う
src/Type/User/User.php

namespace Hpscript\Type\User;

use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use Hpscript\Repository\UserRepository;
use Hpscript\Type\Definition\DomainType;

class User extends ObjectType {

	private $userRepository;

	public function __construct(){
		$this->userRepository = new UserRepository;
		parent::__construct([
			'name' => 'User',
			'fields' => function(){
				return [
					'id' => [
						'type' => Type::int(),
						'resolve' => function($id){
							return $id;
						},
					],
					'name' => [
						'type' => Type::string(),
						'resolve' => function($id){
							return $this->getUser($id)->getName();
						}
					],
					'profile' => [
						'type' => Type::string(),
						'resolve' => function($id){
							return $this->getUser($id)->getProfile();
						}
					],
					'address' => [
						'type' => Type::string(),
						'resolve' => function($id){
							return $this->getUser($id)->getName();
						}
					],
				];
			},
		]);
	}
}

private function getUser($id){
	return $this->userRepository->getUser($id);
}

src/Type/Definition/DomainType.php

namespace Hpscript\Type\Definition;

use Hpscript\Type\User\User;

class DomainType {

	private static $user;

	public static function user(){
		if(!isset(static::$user)){
			static::$user = new User();
		}
		return static::$user;
	}
}

src/Repository/UserRepository.php

namespace Hpscript\Repository;

class UserRepository {

	private $dummyData;

	public function __construct(){
		$sakamoto = new User(1, 'Sakamoto', '坂本太郎', '東京都');
		$sato = new User(2, 'Sato', '佐藤和子', '神奈川');
		$tanaka = new User(3, 'Tanaka', '田中はじめ', '愛知県');
		$this->dummyData = [
			1 => $sakamoto,
			2 => $sato,
			3 => $tanaka
		];
	}

	public function getUser($id){
		data_default_timezone_set('Asia/Tokyo');
		error_log(date('Y-m-d H:i:s') . "\t" . __METHOD__ . "\n", 3, "/tmp/php-graphql-sample.log");
		return $this->dummyData[$id];
	}
}

class User {
	private $id;
	private $name;
	private $profile;
	private $address;

	public function __construct($id, $name, $profile, $address){
		$this->id = $id;
		$this->name = $name;
		$this->profile = $profile;
		$this->address = $address;
	}

	public function getId(){
		return $this->id;
	}
	public function getName(){
		return $this->name;
	}
	public function getProfile(){
		return $this->profile;
	}
	public function getAddress(){
		return $this->address;
	}
}

public/grapql/index.php

require_once __DIR__ . '/../../vendor/autoload.php';

use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Definition\ResolveInfo;
use Hpscript\Type\Definition\DomainType;

class Query extends ObjectType {
	public function __contruct(){
		parent::__construct([
			'name' => 'Query',
			'fields' => [
				'user' => [
					'type' => DomainType::user(),
					'args' => [
						'id' => Type::int(),
					],
					'resolve' => function($value, $args, $context, ResolveInfo $resolveInfo){
						return $args['id'];
					}
				],
			],
		]);
	}
}

$schema = new GraphQL\Type\Schema([
	'query' => new Query(),
]);

$server = new Graph\Server\StandardServer([
	'schema' => $schema
]);

$server->handleRequest();

composer.json

{
	"autoload": {
		"psr-4": {
			"Hpscript\\": "src"
		}
	},
    "require": {
        "webonyx/graphql-php": "^14.9"
    }
}

$ curl -X POST -H “Content-Type: application/json” “http://192.168.34.10:8000/graphql/” -d ‘{“query”: “query { user(id: 2){id name} }”}
POST /graphql/ – Uncaught ArgumentCountError: Too few arguments to function GraphQL\Type\Definition\ObjectType::__construct(), 0 passed in /home/vagrant/dev/graphql/public/graphql/index.php on line 30 and exactly 1 expected in /home/vagrant/dev/graphql/vendor/webonyx/graphql-php/src/Type/Definition/ObjectType.php:86
エラーになるな。mutationはいらないから、querytypeだけで良いような気がするんだが。。