├── .gitignore ├── .php-cs-fixer.php ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── README.md ├── UPGRADE.md ├── composer.json ├── src ├── DownloadAssetsCommand.php ├── GraphQLPlaygroundController.php ├── GraphQLPlaygroundServiceProvider.php ├── graphql-playground.php └── routes.php └── views └── index.blade.php /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated 2 | vendor 3 | composer.lock 4 | .php-cs-fixer.cache 5 | 6 | # IDE 7 | .vscode/ 8 | .idea/ 9 | -------------------------------------------------------------------------------- /.php-cs-fixer.php: -------------------------------------------------------------------------------- 1 | notPath('vendor') 5 | ->in(__DIR__) 6 | ->name('*.php') 7 | ->ignoreDotFiles(true) 8 | ->ignoreVCS(true); 9 | 10 | return MLL\PhpCsFixerConfig\risky($finder); 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## Unreleased 9 | 10 | ## v2.6.0 11 | 12 | ### Added 13 | 14 | - Support Laravel 9 15 | 16 | ## v2.5.0 17 | 18 | ### Added 19 | 20 | - Configure subscription endpoint through `graphql-playground.php` https://github.com/mll-lab/laravel-graphql-playground/pull/48 21 | - Support PHP 8 22 | 23 | ## v2.4.0 24 | 25 | ### Added 26 | 27 | - Support Laravel 8 28 | 29 | ## v2.3.0 30 | 31 | ### Changed 32 | 33 | - Namespace tags for `php artisan vendor:publish` under `graphql-playground-` prefix 34 | 35 | ## v2.2.1 36 | 37 | ### Fixed 38 | 39 | - Fix loading removal by removing remaining bits 40 | 41 | ## v2.2.0 42 | 43 | ### Changed 44 | 45 | - Simplify view by excluding loading animation 46 | 47 | ## v2.1.0 48 | 49 | ### Added 50 | 51 | - Support Laravel 7 52 | 53 | ## v2.0.2 54 | 55 | ### Fixed 56 | 57 | - Lumen compatibility: Do not use `public_path()` helper 58 | 59 | ## v2.0.1 60 | 61 | ### Fixed 62 | 63 | - Lumen compatibility: Remove usage of unavailable path helpers 64 | 65 | ## v2.0.0 66 | 67 | ### Added 68 | 69 | - Support Lumen 70 | - Load routes through a file: `src/routes.php` 71 | 72 | ### Changed 73 | 74 | - Make the `GraphQLPlaygroundController` use `__invoke()` instead of `get()` 75 | - Move the `route_name` configuration option into `route.uri` 76 | 77 | ### Removed 78 | 79 | - Disable the `route.domain` configuration option by default 80 | 81 | ## Pre-v2 82 | 83 | We just started maintaining a changelog starting from v2. 84 | 85 | If someone wants to make one for previous versions, PR's are welcome. 86 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Benedikt Franke 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: it 2 | it: fix ## Perform all quality checks 3 | 4 | .PHONY: help 5 | help: ## Displays this list of targets with descriptions 6 | @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(firstword $(MAKEFILE_LIST)) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}' 7 | 8 | .PHONY: setup 9 | setup: vendor ## Setup the local environment 10 | 11 | .PHONY: fix 12 | fix: ## Fix the codestyle 13 | composer normalize 14 | vendor/bin/php-cs-fixer fix --allow-risky=yes 15 | 16 | vendor: composer.json composer.lock ## Install dependencies through composer 17 | composer install 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel GraphQL Playground 2 | 3 | ## Deprecated 4 | 5 | This project is deprecated in favor of https://github.com/mll-lab/laravel-graphiql. 6 | 7 | Easily integrate [GraphQL Playground](https://github.com/prismagraphql/graphql-playground) into your Laravel projects. 8 | 9 | [](https://github.com/mll-lab/laravel-graphql-playground/blob/master/LICENSE) 10 | [](https://packagist.org/packages/mll-lab/laravel-graphql-playground) 11 | [](https://packagist.org/packages/mll-lab/laravel-graphql-playground) 12 | 13 | [](https://www.graphqlbin.com/RVIn) 14 | 15 | > **Please note**: This is not a GraphQL Server implementation, only a UI for testing and exploring your schema. 16 | > For the server component we recommend [nuwave/lighthouse](https://github.com/nuwave/lighthouse). 17 | 18 | ## Installation 19 | 20 | composer require mll-lab/laravel-graphql-playground 21 | 22 | If you are using Lumen, register the service provider in `bootstrap/app.php` 23 | 24 | ```php 25 | $app->register(MLL\GraphQLPlayground\GraphQLPlaygroundServiceProvider::class); 26 | ``` 27 | 28 | ## Configuration 29 | 30 | By default, the playground is reachable at `/graphql-playground` 31 | and assumes a running GraphQL endpoint at `/graphql`. 32 | 33 | To change the defaults, publish the configuration with the following command: 34 | 35 | php artisan vendor:publish --tag=graphql-playground-config 36 | 37 | You will find the configuration file at `config/graphql-playground.php`. 38 | 39 | ### Lumen 40 | 41 | If you are using Lumen, copy it into that location manually and load the configuration 42 | in your `boostrap/app.php`: 43 | 44 | ```php 45 | $app->configure('graphql-playground'); 46 | ``` 47 | 48 | ### HTTPS behind proxy 49 | 50 | If your application sits behind a proxy which resolves https, the generated URL for the endpoint 51 | might not use `https://`, thus causing the Playground to not work by default. In order to solve 52 | this, configure your `TrustProxies` middleware to contain `\Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_FOR` 53 | in `$headers`. 54 | 55 | ## Customization 56 | 57 | To customize the Playground even further, publish the view: 58 | 59 | php artisan vendor:publish --tag=graphql-playground-view 60 | 61 | You can use that for all kinds of customization. 62 | 63 | ### Change settings of the playground instance 64 | 65 | Add extra settings in the call to `GraphQLPlayground.init` in the published view: 66 | 67 | ```js 68 | GraphQLPlayground.init(document.getElementById('root'), { 69 | endpoint: "{{ url(config('graphql-playground.endpoint')) }}", 70 | subscriptionEndpoint: "{{ config('graphql-playground.subscriptionEndpoint') }}", 71 | // See https://github.com/graphql/graphql-playground#properties for available settings 72 | }) 73 | ``` 74 | 75 | ### Configure session authentication 76 | 77 | Session based authentication can be used with [Laravel Sanctum](https://laravel.com/docs/sanctum). 78 | If you use GraphQL through sessions and CSRF, add the following to the `
` in the published view: 79 | 80 | ```php 81 | 82 | ``` 83 | 84 | Modify the Playground config: 85 | 86 | ```diff 87 | GraphQLPlayground.init(document.getElementById('root'), { 88 | endpoint: "{{ url(config('graphql-playground.endpoint')) }}", 89 | subscriptionEndpoint: "{{ config('graphql-playground.subscriptionEndpoint') }}", 90 | + settings: { 91 | + 'request.credentials': 'same-origin', 92 | + 'request.globalHeaders': { 93 | + 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content 94 | + } 95 | + } 96 | }) 97 | ``` 98 | 99 | Make sure your route includes the `web` middleware group in `config/graphql-playground.php`: 100 | 101 | ```diff 102 | 'route' => [ 103 | 'uri' => '/graphql-playground', 104 | 'name' => 'graphql-playground', 105 | + 'middleware' => ['web'] 106 | ] 107 | ``` 108 | ## Local assets 109 | 110 | If you want to serve the assets from your own server, you can download them with the command 111 | 112 | php artisan graphql-playground:download-assets 113 | 114 | This puts the necessary CSS, JS and Favicon into your `public` directory. If you have 115 | the assets downloaded, they will be used instead of the online version from the CDN. 116 | 117 | ## Security 118 | 119 | If you do not want to enable the GraphQL playground in production, you can disable it in the config file. 120 | The easiest way is to set the environment variable `GRAPHQL_PLAYGROUND_ENABLED=false`. 121 | 122 | If you want to protect the route to the GraphQL playground, you can add custom middleware in the config file. 123 | -------------------------------------------------------------------------------- /UPGRADE.md: -------------------------------------------------------------------------------- 1 | # Upgrade guide 2 | 3 | This document provides guidance for upgrading between major versions. 4 | 5 | ## v1 to v2 6 | 7 | Compare your `graphql-playground.php` against the latest [default configuration](src/graphql-playground.php). 8 | The configuration options for the `route` changed. 9 | 10 | If you were calling the `GraphQLPlaygroundController` directly, change the reference 11 | to use `__invoke()`: 12 | 13 | ```diff 14 | -'uses' => \MLL\GraphQLPlayground\GraphQLPlaygroundController::class . '@get', 15 | +'uses' => \MLL\GraphQLPlayground\GraphQLPlaygroundController::class, 16 | ``` 17 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mll-lab/laravel-graphql-playground", 3 | "description": "Easily integrate GraphQL Playground into your Laravel project", 4 | "license": "MIT", 5 | "keywords": [ 6 | "laravel", 7 | "graphql", 8 | "graphql-playground" 9 | ], 10 | "authors": [ 11 | { 12 | "name": "Benedikt Franke", 13 | "email": "benedikt@franke.tech" 14 | } 15 | ], 16 | "require": { 17 | "php": "^7.1 || ^8", 18 | "illuminate/console": "5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6 || ^7 || ^8 || ^9", 19 | "illuminate/contracts": "5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6 || ^7 || ^8 || ^9", 20 | "illuminate/support": "5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6 || ^7 || ^8 || ^9" 21 | }, 22 | "require-dev": { 23 | "ergebnis/composer-normalize": "^2", 24 | "laravel/lumen-framework": "5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6 || ^7 || ^8 || ^9", 25 | "mll-lab/php-cs-fixer-config": "^4.4" 26 | }, 27 | "minimum-stability": "dev", 28 | "prefer-stable": true, 29 | "autoload": { 30 | "psr-4": { 31 | "MLL\\GraphQLPlayground\\": "src/" 32 | } 33 | }, 34 | "config": { 35 | "allow-plugins": { 36 | "kylekatarnls/update-helper": true, 37 | "ergebnis/composer-normalize": true 38 | }, 39 | "sort-packages": true 40 | }, 41 | "extra": { 42 | "laravel": { 43 | "providers": [ 44 | "MLL\\GraphQLPlayground\\GraphQLPlaygroundServiceProvider" 45 | ] 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/DownloadAssetsCommand.php: -------------------------------------------------------------------------------- 1 | fileForceContents( 25 | self::publicPath(self::CSS_PATH_LOCAL), 26 | file_get_contents('https:' . self::CSS_PATH_CDN) 27 | ); 28 | $this->fileForceContents( 29 | self::publicPath(self::JS_PATH_LOCAL), 30 | file_get_contents('https:' . self::JS_PATH_CDN) 31 | ); 32 | $this->fileForceContents( 33 | self::publicPath(self::FAVICON_PATH_LOCAL), 34 | file_get_contents('https:' . self::FAVICON_PATH_CDN) 35 | ); 36 | } 37 | 38 | protected function fileForceContents(string $filePath, string $contents): void 39 | { 40 | // Ensure the directory exists 41 | $directory = dirname($filePath); 42 | if (! is_dir($directory)) { 43 | mkdir($directory, 0777, true); 44 | } 45 | 46 | file_put_contents( 47 | $filePath, 48 | $contents 49 | ); 50 | } 51 | 52 | public static function jsPath(): string 53 | { 54 | return self::assetPath(self::JS_PATH_LOCAL, self::JS_PATH_CDN); 55 | } 56 | 57 | public static function cssPath(): string 58 | { 59 | return self::assetPath(self::CSS_PATH_LOCAL, self::CSS_PATH_CDN); 60 | } 61 | 62 | public static function faviconPath(): string 63 | { 64 | return self::assetPath(self::FAVICON_PATH_LOCAL, self::FAVICON_PATH_CDN); 65 | } 66 | 67 | protected static function assetPath(string $local, string $cdn): string 68 | { 69 | return file_exists(self::publicPath($local)) 70 | ? self::asset($local) 71 | : $cdn; 72 | } 73 | 74 | protected static function asset(string $path): string 75 | { 76 | return app('url')->asset($path); 77 | } 78 | 79 | protected static function publicPath(string $path): string 80 | { 81 | return app()->basePath("public/{$path}"); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/GraphQLPlaygroundController.php: -------------------------------------------------------------------------------- 1 | loadViewsFrom(self::VIEW_PATH, 'graphql-playground'); 17 | 18 | $this->publishes([ 19 | self::CONFIG_PATH => $this->configPath('graphql-playground.php'), 20 | ], 'graphql-playground-config'); 21 | 22 | $this->publishes([ 23 | self::VIEW_PATH => $this->resourcePath('views/vendor/graphql-playground'), 24 | ], 'graphql-playground-view'); 25 | 26 | if (! $config->get('graphql-playground.enabled', true)) { 27 | return; 28 | } 29 | 30 | $this->loadRoutesFrom(__DIR__ . '/routes.php'); 31 | } 32 | 33 | protected function loadRoutesFrom($path): void 34 | { 35 | if (Str::contains($this->app->version(), 'Lumen')) { 36 | require realpath($path); 37 | 38 | return; 39 | } 40 | 41 | parent::loadRoutesFrom($path); 42 | } 43 | 44 | public function register(): void 45 | { 46 | $this->mergeConfigFrom(self::CONFIG_PATH, 'graphql-playground'); 47 | 48 | if ($this->app->runningInConsole()) { 49 | $this->commands([ 50 | DownloadAssetsCommand::class, 51 | ]); 52 | } 53 | } 54 | 55 | protected function configPath(string $path): string 56 | { 57 | return $this->app->basePath("config/{$path}"); 58 | } 59 | 60 | protected function resourcePath(string $path): string 61 | { 62 | return $this->app->basePath("resources/{$path}"); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/graphql-playground.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'uri' => '/graphql-playground', 16 | 'name' => 'graphql-playground', 17 | // 'middleware' => ['web'] 18 | // 'prefix' => '', 19 | // 'domain' => 'graphql.' . env('APP_DOMAIN', 'localhost'), 20 | ], 21 | 22 | /* 23 | |-------------------------------------------------------------------------- 24 | | Default GraphQL endpoint 25 | |-------------------------------------------------------------------------- 26 | | 27 | | The default endpoint that the Playground UI is set to. 28 | | It assumes you are running GraphQL on the same domain 29 | | as GraphQL Playground, but can be set to any URL. 30 | | 31 | */ 32 | 33 | 'endpoint' => '/graphql', 34 | 35 | /* 36 | |-------------------------------------------------------------------------- 37 | | Subscription endpoint 38 | |-------------------------------------------------------------------------- 39 | | 40 | | The default subscription endpoint Playground UI uses to connect to. 41 | | Tries to connect to the `endpoint` value if `null` as ws://{{endpoint}} 42 | | 43 | | Example: `ws://your-endpoint` or `wss://your-endpoint` 44 | | 45 | */ 46 | 47 | 'subscriptionEndpoint' => env('GRAPHQL_PLAYGROUND_SUBSCRIPTION_ENDPOINT', null), 48 | 49 | /* 50 | |-------------------------------------------------------------------------- 51 | | Control Playground availability 52 | |-------------------------------------------------------------------------- 53 | | 54 | | Control if the playground is accessible at all. 55 | | This allows you to disable it in certain environments, 56 | | for example you might not want it active in production. 57 | | 58 | */ 59 | 60 | 'enabled' => env('GRAPHQL_PLAYGROUND_ENABLED', true), 61 | ]; 62 | -------------------------------------------------------------------------------- /src/routes.php: -------------------------------------------------------------------------------- 1 | get('graphql-playground.route')) { 9 | /** @var \Illuminate\Contracts\Routing\Registrar|\Laravel\Lumen\Routing\Router $router */ 10 | $router = app('router'); 11 | 12 | $actions = [ 13 | 'as' => $routeConfig['name'] ?? 'graphql-playground', 14 | 'uses' => \MLL\GraphQLPlayground\GraphQLPlaygroundController::class, 15 | ]; 16 | 17 | if (isset($routeConfig['middleware'])) { 18 | $actions['middleware'] = $routeConfig['middleware']; 19 | } 20 | 21 | if (isset($routeConfig['prefix'])) { 22 | $actions['prefix'] = $routeConfig['prefix']; 23 | } 24 | 25 | if (isset($routeConfig['domain'])) { 26 | $actions['domain'] = $routeConfig['domain']; 27 | } 28 | 29 | $router->get( 30 | $routeConfig['uri'] ?? '/graphql-playground', 31 | $actions 32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /views/index.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |