Skip to content

Commit

Permalink
Fix for lazy loading dynamically defined types
Browse files Browse the repository at this point in the history
  • Loading branch information
JakeBooher committed Nov 10, 2023
1 parent 74b72dc commit 33975b2
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 34 deletions.
24 changes: 14 additions & 10 deletions src/Providers/GraphQLServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public function boot()

$this->bootPublishes();
$this->bootDebug();
$this->extendRebing();
}

public function register()
Expand Down Expand Up @@ -67,7 +68,7 @@ protected function bootDebug(): void

protected function bootConsole()
{
$this->extendRebing();
$this->extendRebingConsole();
$this->extendBase();

// $this->commands(EnumMakeCommand::class);
Expand All @@ -80,16 +81,8 @@ protected function extendBase()
$this->overrideIlluminateCommand('command.model.make', ModelMakeCommand::class);
}

protected function extendRebing()
protected function extendRebing(): void
{
$this->commands(EnumMakeCommand::class);
$this->commands(TypeMakeCommand::class);
$this->commands(MutationMakeCommand::class);
$this->commands(QueryMakeCommand::class);

$this->commands(BuildSchemaCacheCommand::class);
$this->commands(ClearSchemaCacheCommand::class);

$this->app->singleton(BaseGraphQL::class, function (Container $app): BaseGraphQL {
$config = $app->make(Repository::class);
$graphql = new GraphQL($app, $config);
Expand All @@ -102,6 +95,17 @@ protected function extendRebing()
});
}

protected function extendRebingConsole()
{
$this->commands(EnumMakeCommand::class);
$this->commands(TypeMakeCommand::class);
$this->commands(MutationMakeCommand::class);
$this->commands(QueryMakeCommand::class);

$this->commands(BuildSchemaCacheCommand::class);
$this->commands(ClearSchemaCacheCommand::class);
}

protected function bootPublishes(): void
{
$this->publishes([
Expand Down
99 changes: 75 additions & 24 deletions src/Rebing/GraphQL/GraphQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
namespace Audentio\LaravelGraphQL\Rebing\GraphQL;

use Audentio\LaravelGraphQL\Utils\ServerTimingUtil;
use GraphQL\Type\Definition\Directive;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Introspection;
use GraphQL\Type\Schema;
use Illuminate\Support\Facades\Cache;
use Rebing\GraphQL\GraphQL as BaseGraphQL;
use Audentio\LaravelGraphQL\Opis\Closure\SerializableClosure;
use Rebing\GraphQL\Support\Field;

class GraphQL extends BaseGraphQL
{
Expand All @@ -27,39 +30,87 @@ public static function clearLaravelSchemaCache(?string $schemaName = null): void
$schemaName = $schemaName ?? config()->get('graphql.default_schema', 'default');
$instance->clearSchemaLaravelCache($schemaName);
}

public function schema(?string $schemaName = null, bool $forceRefresh = false): Schema
protected function buildObjectTypeFromFields(array $fields, array $opts = []): ObjectType
{
$suffixKey = substr(md5(rand(0,1000)), 0, 5);
$timingKey = 'GraphQL:loadSchema:' . $suffixKey;
if (!$this->config->get('audentioGraphQL.enableSchemaCache')) {
ServerTimingUtil::start($timingKey);
$return = parent::schema($schemaName);
ServerTimingUtil::stop($timingKey);

return $return;
$typeFields = [];

foreach ($fields as $name => $field) {
if (\is_string($field)) {
$field = $this->app->make($field);
/** @var Field $field */
$field = $field->toArray();

// START CUSTOM CODE FOR DYNAMIC TYPES
$fieldType = $field['type'] ?? null;
if ($fieldType instanceof ObjectType) {
if (!array_key_exists($fieldType->name, $this->types)) {
$this->addType($fieldType);
}
}
// END CUSTOM CODE FOR DYNAMIC TYPES
}
$name = is_numeric($name) ? $field['name'] : $name;
$field['name'] = $name;
$typeFields[$name] = $field;
}

$schemaName = $schemaName ?? $this->config->get('graphql.default_schema', 'default');
return new ObjectType(array_merge([
'fields' => $typeFields,
], $opts));
}

public function addType($class, string $name = null): void
{
parent::addType($class, $name);

if (isset($this->schemas[$schemaName])) {
ServerTimingUtil::start($timingKey);
$return = $this->schemas[$schemaName];
ServerTimingUtil::stop($timingKey);
return $return;
if ($class instanceof ObjectType) {
if (!$name) {
$name = $class->name;
}

$this->typesInstances[$name] = $class;
}
}

public function schema(?string $schemaName = null, bool $forceRefresh = false): Schema
{
$suffixKey = substr(md5(rand(0,1000)), 0, 5);
$timingKey = 'GQL:schema:' . $suffixKey;
ServerTimingUtil::start($timingKey);
if (!$forceRefresh && Cache::has('gqlSchema.' . $schemaName)) {
$schemaConfig = static::getNormalizedSchemaConfiguration($schemaName);
$schema = $this->buildSchemaFromLaravelCache($schemaName, $schemaConfig);
} else {
$schema = parent::schema($schemaName);
$this->storeSchemaInLaravelCache($schemaName, $schema, $this->config->get('audentioGraphQL.schemaCacheTTL'));
}
$return = parent::schema($schemaName);
ServerTimingUtil::stop($timingKey);

return $schema;
// Cache is disabled as performance is much worse.
// if (!$this->config->get('audentioGraphQL.enableSchemaCache')) {
// ServerTimingUtil::start($timingKey);
// $return = parent::schema($schemaName);
// ServerTimingUtil::stop($timingKey);
//
// return $return;
// }
//
// $schemaName = $schemaName ?? $this->config->get('graphql.default_schema', 'default');
//
// if (isset($this->schemas[$schemaName])) {
// ServerTimingUtil::start($timingKey);
// $return = $this->schemas[$schemaName];
// ServerTimingUtil::stop($timingKey);
// return $return;
// }
//
// ServerTimingUtil::start($timingKey);
// if (!$forceRefresh && Cache::has('gqlSchema.' . $schemaName)) {
// $schemaConfig = static::getNormalizedSchemaConfiguration($schemaName);
// $schema = $this->buildSchemaFromLaravelCache($schemaName, $schemaConfig);
// } else {
// $schema = parent::schema($schemaName);
// $this->storeSchemaInLaravelCache($schemaName, $schema, $this->config->get('audentioGraphQL.schemaCacheTTL'));
// }
// ServerTimingUtil::stop($timingKey);
//
// return $schema;

return $return;
}

public function storeSchemaInLaravelCache(string $schemaName, Schema $schema, ?int $duration = 300)
Expand Down

0 comments on commit 33975b2

Please sign in to comment.