Graphqlbundle: subscriptionType ?

Created on 18 May 2017  路  7Comments  路  Source: overblog/GraphQLBundle

| Q | A
| ---------------- | -----
| Bug report? |no
| Feature request? | yes
| BC Break report? |no
| RFC? | no
| Version/Branch | x.y.z

is there a possibility to add subscription type to the bundle or make another compatible bundle like the data loader
i think this would be possible with a library like ratchet
they already discussed the issue in webonyx
https://github.com/webonyx/graphql-php/issues/9

feature

Most helpful comment

subscription server and subscription manager are two files i got from siler:
https://github.com/leocavalcante/siler/tree/master/src/Graphql

since they rely on a function specific to the framework yo need to add it

` /*
* array get function imported from sliler root
*/

public function array_get($array, $key = null, $default = null)
{
    if (is_null($key)) {
        return $array;
    }
    return array_key_exists($key, $array) ? $array[$key] : $default;
}`

All 7 comments

webonyx/graphql-php is the best place to debate about this, the bundle is just the symfony implementation. This feature is requiring a direct implementation in the main lib... Maybe using this https://siler.leocavalcante.com/graphql/subscriptions.html could also helps...

feel free to reopen if needed...

sorry for reopening this issue after a long time, i decided to implement subscription on top of your bundle, siler's example works when you create a symfony command that runs ratchet on a different port, i can pass the schema to the websocket server, however subscription resolvers need to take the payload in the function argument instead of the query variables, and i found some difficulties to add a new type of resolvers to your bundle,

@omarsoufiane can you provide some snippets of the issue please ?

first graphiql and react needs a higher default version on the config
and subscription types work by default
`overblog_graphql:

versions:
    graphiql: 0.9.3
    react:  15.4.2
definitions:
    schema:
        query: Query
        mutation: Mutation
        subscription: Subscription`

you need a class with a subscribe and publish method that we will register as a service to use it in the sumfony command and mutation resolver

`use GraphQL\Schema;

use Ratchet\Client;
use Ratchet\Client\WebSocket;
use Ratchet\Http\HttpServer;
use Ratchet\Server\IoServer;
use Ratchet\WebSocket\WsServer;

const INIT = 'init';
const INIT_SUCCESS = 'init_success';
const INIT_FAIL = 'init_fail';
const SUBSCRIPTION_START = 'subscription_start';
const SUBSCRIPTION_END = 'subscription_end';
const SUBSCRIPTION_SUCCESS = 'subscription_success';
const SUBSCRIPTION_FAIL = 'subscription_fail';
const SUBSCRIPTION_DATA = 'subscription_data';

class Subscription
{

protected $host;
protected $port;

/**
 * SubscriptionCommand constructor.
 * @param $host
 * @param $port
 */
public function __construct($host, $port)
{
    $this->host = $host;
    $this->port = $port;
}

/**
 * Returns a new websocket server bootstraped for GraphQL subscriptions.
 *
 * @param Schema $schema
 * @param array $filters
 * @param array $rootValue
 * @param array $context
 * @param int $port
 * @param string $host
 * @return IoServer
 */
function subscribe(
    Schema $schema,
    array $filters = null,
    array $rootValue = null,
    array $context = null,
    $port = 7070,
    $host = '0.0.0.0'
) {
    $manager = new SubscriptionManager($schema, $filters, $rootValue, $context);
    $server = new SubscriptionServer($manager);
    $websocket = new WsServer($server);
    $websocket->disableVersion(0);
    $http = new HttpServer($websocket);
    return IoServer::factory($http, $port, $host);
}




/**
 * Publishes the given $payload to the $subscribeName.
 *
 * @param string $subscriptionName
 * @param mixed  $payload
 */
function publish($subscriptionName, $payload = null)
{
    Client\connect('ws://127.0.0.1:7070')->then(function (WebSocket $conn) use ($subscriptionName, $payload) {
        $request = [
            'type'         => SUBSCRIPTION_DATA,
            'subscription' => $subscriptionName,
            'payload'      => $payload,
        ];
        $conn->send(json_encode($request));
        $conn->close();
    });
}

}`

then create a command that runs the websocket server on a different port

`class SubscriptionCommand extends ContainerAwareCommand
{
/**
* Configure a new Command Line
*/
protected function configure()
{
$this
->setName('graphql:subscription:server')
->setDescription('Start the notification server.')
->addOption(
'file',
null,
InputOption::VALUE_OPTIONAL,
'Path to generate schema file.'
)
->addOption(
'schema',
null,
InputOption::VALUE_OPTIONAL,
'The schema name to generate.'
)

    ;
}

protected function execute(InputInterface $input, OutputInterface $output)
{

    $output = new SymfonyStyle($input, $output);


    $container = $this->getContainer();

//the problem is here i guess, the schema already has resolvers and they don't accept payloads as //function argument
$schema = $container
->get('overblog_graphql.request_executor')
->getSchema();

//filters is a way to know which subscription should recieve data after you send a mutation as explained in siler
    $filters = [
        'inbox' => function ($payload, $vars) {
            return ($payload['roomid'] == $vars['roomid']) ;
        },
    ];
    $subscription = $container->get('subscription_command');
    $subscription->subscribe($schema, $filters)->run();
}

}`

subscription server and subscription manager are two files i got from siler:
https://github.com/leocavalcante/siler/tree/master/src/Graphql

since they rely on a function specific to the framework yo need to add it

` /*
* array get function imported from sliler root
*/

public function array_get($array, $key = null, $default = null)
{
    if (is_null($key)) {
        return $array;
    }
    return array_key_exists($key, $array) ? $array[$key] : $default;
}`

thank you for the example. I don't have a lot of time to work on that right now but hope to get a look more carefully on this before the weekend...

Was this page helpful?
0 / 5 - 0 ratings