├── .gitignore ├── composer.json ├── composer.lock ├── index.php ├── resolvers.php ├── schema.graphql ├── schema.php └── test.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | .vscode -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "webonyx/graphql-php": "^0.11.5", 4 | "leocavalcante/siler": "^1.0", 5 | "overblog/dataloader-php": "^0.5.2" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "c91d6b0c0709d6997c61e715f19040d3", 8 | "packages": [ 9 | { 10 | "name": "leocavalcante/siler", 11 | "version": "v1.0.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/leocavalcante/siler.git", 15 | "reference": "5cf7dc720a4000fe247f69cb8b56e94fda32c6ad" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/leocavalcante/siler/zipball/5cf7dc720a4000fe247f69cb8b56e94fda32c6ad", 20 | "reference": "5cf7dc720a4000fe247f69cb8b56e94fda32c6ad", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": ">=7.1" 25 | }, 26 | "require-dev": { 27 | "cboden/ratchet": "^0.4.1", 28 | "gabordemooij/redbean": "^5.0.0", 29 | "lcobucci/jwt": "^3.2.2", 30 | "phpstan/phpstan": "^0.9.2", 31 | "phpunit/phpunit": "^7.0.2", 32 | "ratchet/pawl": "^0.3.1", 33 | "react/http": "^0.8.1", 34 | "squizlabs/php_codesniffer": "^3.2.3", 35 | "twig/twig": "^2.4.7", 36 | "vimeo/psalm": "^1.0.4", 37 | "vlucas/phpdotenv": "^2.4.0", 38 | "webonyx/graphql-php": "^0.11.5", 39 | "zendframework/zend-diactoros": "^1.7.1" 40 | }, 41 | "suggest": { 42 | "vlucas/phpdotenv": "Storing configuration in the environment is one of the tenets of a twelve-factor app." 43 | }, 44 | "type": "library", 45 | "autoload": { 46 | "psr-4": { 47 | "Siler\\": "src/" 48 | }, 49 | "files": [ 50 | "src/Container/Container.php", 51 | "src/Diactoros/Diactoros.php", 52 | "src/Dotenv/Dotenv.php", 53 | "src/Functional/Functional.php", 54 | "src/Functional/Monad/Monad.php", 55 | "src/Graphql/Graphql.php", 56 | "src/Http/Http.php", 57 | "src/Http/Request.php", 58 | "src/Http/Response.php", 59 | "src/Jwt/Jwt.php", 60 | "src/Ratchet/Ratchet.php", 61 | "src/Route/Route.php", 62 | "src/Siler.php", 63 | "src/Twig/Twig.php" 64 | ] 65 | }, 66 | "notification-url": "https://packagist.org/downloads/", 67 | "license": [ 68 | "MIT" 69 | ], 70 | "authors": [ 71 | { 72 | "name": "leocavalcante", 73 | "email": "lc@leocavalcante.com" 74 | } 75 | ], 76 | "description": "Siler is a set of general purpose high-level abstractions aiming an API for declarative programming in PHP.", 77 | "keywords": [ 78 | "api", 79 | "framework", 80 | "functional", 81 | "micro", 82 | "router" 83 | ], 84 | "time": "2018-03-22T03:39:00+00:00" 85 | }, 86 | { 87 | "name": "overblog/dataloader-php", 88 | "version": "v0.5.2", 89 | "source": { 90 | "type": "git", 91 | "url": "https://github.com/overblog/dataloader-php.git", 92 | "reference": "49832277a0c4fe4193115f686ed8acdfbb356904" 93 | }, 94 | "dist": { 95 | "type": "zip", 96 | "url": "https://api.github.com/repos/overblog/dataloader-php/zipball/49832277a0c4fe4193115f686ed8acdfbb356904", 97 | "reference": "49832277a0c4fe4193115f686ed8acdfbb356904", 98 | "shasum": "" 99 | }, 100 | "require": { 101 | "php": "^5.5|^7.0" 102 | }, 103 | "replace": { 104 | "overblog/promise-adapter": "self.version" 105 | }, 106 | "require-dev": { 107 | "guzzlehttp/promises": "^1.3.0", 108 | "phpunit/phpunit": "^4.1|^5.1", 109 | "react/promise": "^2.5.0", 110 | "webonyx/graphql-php": "^0.9.14" 111 | }, 112 | "suggest": { 113 | "guzzlehttp/promises": "To use with Guzzle promise", 114 | "react/promise": "To use with ReactPhp promise", 115 | "webonyx/graphql-php": "To use with Webonyx GraphQL native promise" 116 | }, 117 | "type": "library", 118 | "extra": { 119 | "branch-alias": { 120 | "dev-master": "0.5-dev" 121 | } 122 | }, 123 | "autoload": { 124 | "psr-4": { 125 | "Overblog\\DataLoader\\": "src/", 126 | "Overblog\\PromiseAdapter\\": "lib/promise-adapter/src/" 127 | } 128 | }, 129 | "notification-url": "https://packagist.org/downloads/", 130 | "license": [ 131 | "MIT" 132 | ], 133 | "description": "DataLoaderPhp is a generic utility to be used as part of your application's data fetching layer to provide a simplified and consistent API over various remote data sources such as databases or web services via batching and caching.", 134 | "keywords": [ 135 | "Batching", 136 | "caching", 137 | "dataLoader" 138 | ], 139 | "time": "2017-08-18T17:10:51+00:00" 140 | }, 141 | { 142 | "name": "webonyx/graphql-php", 143 | "version": "v0.11.5", 144 | "source": { 145 | "type": "git", 146 | "url": "https://github.com/webonyx/graphql-php.git", 147 | "reference": "b97cad0f4a50131c85d9224e8e36ebbcf1c6b425" 148 | }, 149 | "dist": { 150 | "type": "zip", 151 | "url": "https://api.github.com/repos/webonyx/graphql-php/zipball/b97cad0f4a50131c85d9224e8e36ebbcf1c6b425", 152 | "reference": "b97cad0f4a50131c85d9224e8e36ebbcf1c6b425", 153 | "shasum": "" 154 | }, 155 | "require": { 156 | "ext-mbstring": "*", 157 | "php": ">=5.5,<8.0-DEV" 158 | }, 159 | "require-dev": { 160 | "phpunit/phpunit": "^4.8", 161 | "psr/http-message": "^1.0" 162 | }, 163 | "suggest": { 164 | "psr/http-message": "To use standard GraphQL server", 165 | "react/promise": "To leverage async resolving on React PHP platform" 166 | }, 167 | "type": "library", 168 | "autoload": { 169 | "files": [ 170 | "src/deprecated.php" 171 | ], 172 | "psr-4": { 173 | "GraphQL\\": "src/" 174 | } 175 | }, 176 | "notification-url": "https://packagist.org/downloads/", 177 | "license": [ 178 | "BSD" 179 | ], 180 | "description": "A PHP port of GraphQL reference implementation", 181 | "homepage": "https://github.com/webonyx/graphql-php", 182 | "keywords": [ 183 | "api", 184 | "graphql" 185 | ], 186 | "time": "2017-12-12T09:03:21+00:00" 187 | } 188 | ], 189 | "packages-dev": [], 190 | "aliases": [], 191 | "minimum-stability": "stable", 192 | "stability-flags": [], 193 | "prefer-stable": false, 194 | "prefer-lowest": false, 195 | "platform": [], 196 | "platform-dev": [] 197 | } 198 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | connect_errno) { 19 | error_log("Failed to connect to MySQL: (" . $MyDB->connect_errno . ") " . $MyDB->connect_error); 20 | } 21 | 22 | function sql($query) { 23 | global $MyDB; 24 | $result = mysqli_query($MyDB, $query); 25 | $rows = mysqli_fetch_all($result, MYSQLI_ASSOC); 26 | 27 | return $rows; 28 | } 29 | 30 | $graphQLSyncPromiseAdapter = new SyncPromiseAdapter(); 31 | $promiseAdapter = new WebonyxGraphQLSyncPromiseAdapter($graphQLSyncPromiseAdapter); 32 | 33 | $petLoader = new DataLoader(function ($keys) use ($promiseAdapter ) { 34 | $ids = join(',', $keys); 35 | $idMap = array_flip($keys); 36 | $rows = sql("SELECT owner, isDog, sound FROM pets WHERE owner in ({$ids});"); 37 | foreach ($rows as $r) { 38 | $idMap[$r['owner']] = $r; 39 | } 40 | return $promiseAdapter->createAll(array_values($idMap)); 41 | }, $promiseAdapter); 42 | 43 | WGraphQL::setPromiseAdapter($graphQLSyncPromiseAdapter); 44 | 45 | $context = [ 46 | 'petLoader' => $petLoader, 47 | 'sql' => function ($query) { 48 | return sql($query); 49 | } 50 | ]; 51 | 52 | if (Request\method_is('post')) { 53 | $schema = include __DIR__.'/schema.php'; 54 | 55 | Graphql\init($schema, null, $context); 56 | } 57 | -------------------------------------------------------------------------------- /resolvers.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'pet' => function($root, $args, $context) { 8 | return $context['petLoader']->load($root['id']); 9 | }, 10 | ], 11 | 'Query' => [ 12 | 'getPeople' => function($root, $args, $context) { 13 | return $context['sql']("SELECT name, id FROM people"); 14 | } 15 | ] 16 | ]; 17 | -------------------------------------------------------------------------------- /schema.graphql: -------------------------------------------------------------------------------- 1 | type Query { 2 | getPeople: [Person] 3 | } 4 | 5 | type Person { 6 | name: String 7 | pet: Pet 8 | } 9 | 10 | type Pet { 11 | isDog: Boolean 12 | sound: String 13 | } 14 | -------------------------------------------------------------------------------- /schema.php: -------------------------------------------------------------------------------- 1 | connect_errno) { 6 | error_log("Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error); 7 | } 8 | 9 | function sql($query) { 10 | global $MyDB; 11 | echo $query; 12 | $result = mysqli_query($MyDB, $query); 13 | $rows = mysqli_fetch_all($result, MYSQLI_ASSOC); 14 | 15 | return $rows; 16 | } 17 | 18 | $id = 1; 19 | 20 | $res = sql("SELECT isDog, sound FROM pets WHERE owner = {$id};")[0]; 21 | echo print_r($res, true); --------------------------------------------------------------------------------