-
-
Save nuryagdym/57f4734639213b6f4b81676f425370f5 to your computer and use it in GitHub Desktop.
api-platform v3 - Create a service for Bramble GraphQl Federation Support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# if you have TRUSTED_HOSTS config in your environments, | |
# add host.docker.internal into it so that local development with docker works | |
TRUSTED_HOSTS=^(localhost|php|host.docker.internal)$ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
api_platform: | |
title: GraphQL API | |
version: 1.0.0 | |
formats: | |
jsonld: ['application/ld+json'] | |
# Bramble sends content-type: application/json; charset=utf-8 | |
graphql: ['application/graphql', "application/json; charset=utf-8"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Util; | |
class BrambleSchemaAdapter | |
{ | |
/** | |
* Changes service type to be compatible with Bramble requirements | |
*/ | |
public function execute(string $graphqlSchema): string | |
{ | |
$fixedSchema = \str_replace("service: Service\n", "service: Service!\n", $graphqlSchema); | |
$fixedSchema = \str_replace("type Service implements Node {", "type Service {", $fixedSchema); | |
// removes `id: ID!` field from service schema | |
$fixedSchema = \preg_replace("/type Service {\n\s+id: ID!/", "type Service {", $fixedSchema); | |
return $fixedSchema; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\ApiResource; | |
use ApiPlatform\Metadata\ApiResource; | |
use ApiPlatform\Metadata\Get; | |
use ApiPlatform\Metadata\GraphQl\Query; | |
use App\Resolver\BrambleServiceResolver; | |
/** | |
* Needed resource for Bramble SuperGraph to work | |
*/ | |
#[ApiResource( | |
shortName: 'Service', | |
types: [], | |
operations: [ | |
// Although we don't need RestAPI endpoint, without this operation we get error: "Not able to retrieve identifiers." | |
new Get(), | |
], | |
graphQlOperations: [ | |
new Query( | |
resolver: BrambleServiceResolver::class, | |
args: [ // set args empty so that it does not require ID input | |
], | |
), | |
], | |
)] | |
class BrambleService | |
{ | |
public function __construct( | |
public readonly string $version, | |
public readonly string $schema, | |
public readonly string $name = 'my-service-1', | |
) | |
{ | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Resolver; | |
use ApiPlatform\GraphQl\Resolver\QueryItemResolverInterface; | |
use App\ApiResource\BrambleService; | |
use App\Service\GraphQL\SchemaGeneratorService; | |
class BrambleServiceResolver implements QueryItemResolverInterface | |
{ | |
public function __construct( | |
private readonly SchemaGeneratorService $schemaGeneratorService, | |
) {} | |
/** | |
* @param BrambleService|null $item | |
* | |
* @return BrambleService | |
*/ | |
public function __invoke($item, array $context): BrambleService | |
{ | |
$version = '1.0.0' // make it dynamic | |
return new BrambleService( | |
$version, | |
$this->schemaGeneratorService->getSchema($version), | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Service\GraphQL; | |
use App\Util\BrambleSchemaAdapter; | |
use Symfony\Bundle\FrameworkBundle\Console\Application; | |
use Symfony\Component\Console\Input\ArrayInput; | |
use Symfony\Component\Console\Output\NullOutput; | |
use Symfony\Component\DependencyInjection\Attribute\Autowire; | |
use Symfony\Component\HttpKernel\KernelInterface; | |
class SchemaGeneratorService | |
{ | |
public function __construct( | |
#[Autowire(param: 'kernel.project_dir')] | |
private readonly string $projectDir, | |
private readonly KernelInterface $kernel, | |
private readonly BrambleSchemaAdapter $brambleSchemaAdapter, | |
) {} | |
public function getSchema(string $version): string | |
{ | |
$schemaPath = \sprintf('%s/var/schema-%s.graphql', $this->projectDir, $version); | |
if (!\file_exists($schemaPath)) { | |
$this->generateSchema($schemaPath); | |
} | |
$content = \file_get_contents($schemaPath); | |
return $this->brambleSchemaAdapter->execute($content); | |
} | |
private function generateSchema(string $schemaPath): int | |
{ | |
$application = new Application($this->kernel); | |
$application->setAutoExit(false); | |
$input = new ArrayInput([ | |
'command' => 'api:graphql:export', | |
'--output' => $schemaPath, | |
]); | |
return $application->run($input, new NullOutput()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
API-Platform v3.2
Description about the solution.
Bramble GraphQl Federation requires to creating following type and query:
The first issue with this type is API-Platform always needs an ID for resources and it always adds it to all resource implicitly.
The second one is to make query type required
Service!
instead ofService
.In order Bramble to work these services must be defined exactly as it is. For example, having an additional field such as id in type Service will cause Bramble to fail.
I could not find a proper way of solving this issues currently, so I ended up with this solution, by:
service: Service
instead ofservice(id: ID!): Service
. This is done by settingnew Query(args: [])
.service.schema
that is shared with Bramble usingBrambleSchemaAdapter
so that Bramble accepts it. If we generate schema with implementation above (php bin/console api:graphql:export -o ./schema.graphql
) it will out put following schema:and
BrambleSchemaAdapter
converts it to:You will also need to allow few headers in Bramble
config.json
: