https://github.com/fnash/graphql-on-rest-bundle
Build a GraphQL layer on top of a Rest server (API platform + Rest + json-ld)
https://github.com/fnash/graphql-on-rest-bundle
api-platform graphql json-ld rest symfony-bundle
Last synced: 3 months ago
JSON representation
Build a GraphQL layer on top of a Rest server (API platform + Rest + json-ld)
- Host: GitHub
- URL: https://github.com/fnash/graphql-on-rest-bundle
- Owner: fnash
- License: mit
- Created: 2018-11-09T15:18:03.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2019-07-08T13:52:07.000Z (over 6 years ago)
- Last Synced: 2025-10-10T17:16:17.245Z (3 months ago)
- Topics: api-platform, graphql, json-ld, rest, symfony-bundle
- Language: PHP
- Size: 22.5 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# GraphqlOnRestBundle
Main goal: Write a graphQL query, it will navigate your (Rest + JSON-LD) server and do the HTTP calls for you.
This Symfony bundle lets you build a GraphQL layer to automate HTTP calls to an API Platform based server (JSON-LD + REST).
It is built on top of webonyx/graphql-php.
Includes
============
- Command to validate graphql schema
```bash
$ bin/console graphql_on_rest:schema:validate
```
- Data profiler to dump GraphQL queries et HTTP requests
Installation
============
Download the bundle
----------------
```bash
$ composer require fnash/graphql-on-rest-bundle
```
Register in the Kernel
----------------
```php
serializer = $serializer;
$this->guzzle = $guzzle;
}
/**
* @{inheritdoc}
*/
public function getRawData(string $url, array $queryParams = []): array
{
try {
$data = (string) $this->guzzle->get($url, $queryParams)->getBody();
return $this->serializer->decode($data, 'json');
} catch (\Exception $exception) {
return [];
}
//TODO fill example with symfony/http-client and json_decode (without serializer)
}
/**
* @param string $iri
*
* @return array
*/
public function getIri(string $iri, $context = null): array
{
// TODO: Implement getIri() method.
}
/**
* @param array $iris
*
* @return array[]
*/
public function getIris(array $iris, $context = null): array
{
// TODO: Implement getIris() method.
}
}
```
Build your GraphQL Schema
----------------------------------
Make sure webonyx/graphql-php is installed
1- Define types for your queries:
```php
function () use ($iriResolver) {
$fields = [
'title' => Type::string(),
'body' => Type::string(),
'related' => [
'type' => Type::listOf(TypeRegistry::get(ArticleType::class)),
'resolve' => $iriResolver,
],
'tags' => [
'type' => Type::listOf(TypeRegistry::get(TagType::class)),
'resolve' => $iriResolver,
],
];
return array_merge($fields, TypeRegistry::getInterface(ContentInterfaceType::class)->getFields());
},
'resolveField' => TypeResolver::resolveFieldClosure(),
];
parent::__construct($config);
}
}
namespace Acme\AppBundle\GraphQL\Type;
use Fnash\GraphqlOnRestBundle\GraphQL\Type\JsonLdObjectType;
use GraphQL\Type\Definition\Type;
class TagType extends JsonLdObjectType
{
public function __construct()
{
$config = [
'fields' => function () {
$fields = [
'label' => Type::string(),
];
return array_merge($fields, static::getMetaDataFields());
},
];
parent::__construct($config);
}
}
```
2- Create resolvers for your types to fetch data:
```php
namespace Acme\AppBundle\GraphQL\Resolver;
use Fnash\GraphqlOnRestBundle\GraphQL\Type\TypeRegistry;
use Fnash\GraphqlOnRestBundle\GraphQL\TypeResolver\TypeResolver;
use Acme\AppBundle\GraphQL\Type\ArticleType;
use GraphQL\Type\Definition\Type;
class ArticleTypeResolver extends TypeResolver
{
/**
* {@inheritdoc}
*/
public function getQueryFieldConfig(): array
{
$type = $this->getType();
$type->resolveFieldFn = static::resolveFieldClosure();
$this->configureArguments([
'id' => Type::listOf(Type::string()),
'title',
]);
return [
'type' => Type::listOf($type),
'resolve' => $this->resolveTypeClosure($this->getUrlPath()),
'args' => $this->getArgumentsConfig(),
];
}
/**
* {@inheritdoc}
*/
public function getType(): Type
{
return TypeRegistry::get(ArticleType::class, [
$this->resolveIriDeferredClosure(),
]);
}
}
getType();
$type->resolveFieldFn = static::resolveFieldClosure();
return [
'type' => Type::listOf($type),
'resolve' => $this->resolveTypeClosure($this->getUrlPath()),
'args' => $this->getArgumentsConfig(),
];
}
/**
* {@inheritdoc}
*/
public function getType(): Type
{
return TypeRegistry::get(TagType::class);
}
}
```
- Resolvers must be declared as services and tagged
```yaml
services:
Acme\AppBundle\GraphQL\Resolver\ArticleTypeResolver:
parent: 'graphql_on_rest.type_resolver.my_rest_api'
tags:
- { name: 'graphql_on_rest.type_resolver', server: 'my_rest_api' }
Acme\AppBundle\GraphQL\Resolver\TagTypeResolver:
parent: 'graphql_on_rest.type_resolver.my_rest_api'
tags:
- { name: 'graphql_on_rest.type_resolver', server: 'my_rest_api' }
```
Execute your queries
----------------------------------
Query 1:
```graphql
{
article {
title
body
}
}
```
Result:
```graphql
{
"data": {
"article": [
{
"title": "Nissan rappelle 2 millions de voitures dans le monde",
"body": "
AFP - Le constructeur automobile japonais Nissan a annoncé jeudi
"
},
{
"title": "Vols suspects en série chez les journalistes travaillant sur l'affaire Bettencourt",
"body": "
Des enregistrements réalisés chez Liliane Bettencourt...
"
}
]
},
"extensions": {
"http_calls": [
{
"url": "/api/articles?limit=2",
"duration_ms": 355.484
}
],
"query": {
"duration_ms": 379,
"duration_no_http_ms": 6.554
}
}
}
```
Query 2:
```graphql
{
article {
title
body
tags {
label
}
}
}
```
Result:
```graphql
{
"data": {
"article": [
{
"title": "Nissan rappelle 2 millions de voitures dans le monde",
"body": "
AFP - Le constructeur automobile japonais Nissan a annoncé jeudi
"
"tags": []
},
{
"title": "Vols suspects en série chez les journalistes travaillant sur l'affaire Bettencourt",
"body": "
Des enregistrements réalisés chez Liliane Bettencourt...
"
"tags": [
{
"label": "Justice"
},
{
"label": "France"
},
{
"label": "Affaire Bettencourt"
},
{
"label": "dépêches"
}
]
}
]
},
"extensions": {
"http_calls": [
{
"url": "/api/articles?limit=2",
"duration_ms": 340.168
},
{
"url": "/api/tags?id[0]=8f498ca0-ba33-11e7-add7-02420a050002&id[1]=8f3afcee-ba33-11e7-a697-02420a050002&id[2]=8f1eebee-ba33-11e7-b2fe-02420a050002&id[3]=8a6d60ee-ba33-11e7-9177-02420a050002&limit=4",
"duration_ms": 91.786
}
],
"query": {
"duration_ms": 470,
"duration_no_http_ms": 18.419
}
}
}
```
TODO
============
- update webonyx version