Comments (24)
Here is the first beta release for lighthouse-ws! Currently, it requires Redis, it works w/ Passport to inject the authenticated user into context, and provides an in-memory storage solution for subscriptions. You can extend the SubscriptionManager (for storage) and ContextManager (to generate your own context) if you prefer to create your own solutions here. Before the v1.0 release RedisStorage will be available.
Subscription events can be broadcasted using the custom broadcaster lighthouse
(which will fire a subscription event when any Laravel event is triggered) and implements the ShouldBroadcast
interface or you can use the @websocket
directive to send any mutation result over to lighthouse-ws
.
The @subscription
directive works similar to @field
. Your subscription classes should extend the Nuwave\Lighthouse\Subscriptions\Schema\Fields\SubscriptionField
class and define a resolve
function. You can also define a can
function to allow/reject clients from subscribing to certain subscriptions and a transform
method to transform the event that was fired over Redis. Before the v1.0
release I'll create a default SubscriptionField
class if none is defined that will just pass along whatever was sent via the event.
Big shout out to @TGNThump for providing some great direction on the initial structure!
from lighthouse.
Hello @chrissm79, superb work you have done on this so far. Kudos!
Please, is there any chance we might get a video walkthrough for Subscriptions
? I believe one would be very apt. Thank you!
from lighthouse.
Figure I might as well integrate it the whole way.
from lighthouse.
Hey @chrissm79 completely half baked thought here that is probably entirely down the wrong track, but is there any way to leverage Laravel echo as the websocket provider?
Also, what I'm most curious about here is what api you're looking at implementing for these in terms of the .graphql schema?
from lighthouse.
@TGNThump sorry for the misunderstanding, but yes you're dead on! I think it's possible, it's just more efficient to go in another direction for now and then come back and see if I can tackle Echo (i.e., maybe making a custom queue driver).
from lighthouse.
I've gotten subscriptions working with lighthouse by setting up a Ratchet\WebSocket server that runs on a Laravel Command and conforms to the https://github.com/apollographql/subscriptions-transport-ws protocol.
I fire an event on a subscription using a custom directive to make my schema cleaner, but using @event
would work just as well. All the event listener does is connect to the websocket server and send over the event data.
The websocket server is handling storing the users Passport token and verifying it before every subscription / event and pushing data to the clients by calling graphql()->execute()
for each subscription. I modified the Context class to include an $event variable that contains the event passed to the server, and passed to the subscription resolvers.
WebsocketController: https://gist.github.com/TGNThump/8865041b4626fe00a0c45a087ff82a32
from lighthouse.
Its great to connect with pusher through lighthouse. Is there anyway to connect with PHP Swoole ?
from lighthouse.
thanks, great job with this package 👍
from lighthouse.
Hi @chrissm79,
Subscriptions is indeed my last number one feature for lighthouse, great to hear you're making progress! Since I currently have already a Node ws server running I'd be happy to see where I can help to get this up and running with it.
Redis is also my preferred store for queues and websocket storage..
I'll have a look at Ratchet as well. Interested also in a Laravel Echo implementation as mentioned by @hailwood
from lighthouse.
@hailwood @4levels Echo is a pretty interesting prospect, but I feel like I'm jamming a round peg through a square hole at the moment... specifically when attempting to customize data being sent down to the client based on the query they're subscribing to.
From my previous tests, I can send something like a Post model via the broadcast event, but what if the user subscribed to something like this:
subscription onPostCreated {
postCreated {
title
comments {
# ...
# How do we know that this client wants the post AND comments?
}
}
}
I don't see how I can adjust the broadcastWith method on the event based on the client's subscription request to include the comments or (and more importantly) use defined resolvers for each object type/field.
However, I REALLY like the idea of using Echo as it lowers the barrier of adoption even more so I will certainly circle back to it when the time comes!
from lighthouse.
At that point, isn't it functionally the same as executing the following?
{
post(id: [newPostIdFromTheEvent]) {
title
comments {
...
}
}
}
from lighthouse.
@TGNThump If you're asking if you could just send a query when a subscription gets sent down then yes, but then you don't even need GraphQL subscriptions, you could just use Echo and pull down/refetch when a certain event is fired.
However, that's not the purpose of GraphQL subscriptions (or Echo really) since that means that you have everyone pulling from your server at the same time when the event fires rather than having the data they want pushed down to them.
from lighthouse.
@chrissm79, no I meant executing on the server, but I suppose the problem would be that the broadcastWith would be different for each client... I see where you're coming from.
I suppose you'd have to use a separate channel / echo event for every subscription by every client.
from lighthouse.
@TGNThump, damn that looks nice! The only thing I had left on my version was generating and storing the context, but it's pretty verbose and I needed to clean things up quite a bit before release. Your solution looks extremely streamlined and easy to understand 👍 I'll check it out in depth but thank you for providing this!!!
from lighthouse.
Hi @chrissm79,
I'm finally able to get my hands dirty on this, but I'm a bit struggling how to go about, well, everything 😕
Let's say I want my end users to be able to subscribe to eg. a list of posts so that as soon as a post is added by someone, everyone gets the new post.
Am I supposed to simply do composer require nuwave/lighthouse-ws
in my current project (alongside with lighthouse itself)?
And how do I then define a subscription directive in the schema?
What do I need to run to have lighthouse-ws actually spin up a websocket server (listening to the redis queue)? And how do I trigger the broadcast?
Sorry for asking pbbly very obvious instructions here..
Since I'm using Lumen, this is what I've done so far:
- installed lighthouse-ws with
composer require nuwave/lighthouse-ws
- copied the config to
config/lighthouse_subscriptions.php
- add the configure command to
bootstrap/app.php
$app->configure('lighthouse_subscriptions');
- added the following service providers in
boostrap/app.php
:$app->register(\App\Providers\EventServiceProvider::class);
$app->register(\Illuminate\Redis\RedisServiceProvider::class);
$app->register(\Illuminate\Broadcasting\BroadcastServiceProvider::class);
$app->register(\Nuwave\Lighthouse\Subscriptions\SubscriptionServiceProvider::class);
So when I run php artisan lighthouse:subscriptions
I do get the following output (in purple):
18/05/19 22:55:48| | |Starting Websocket Service on port 9000 - 0
18/05/19 22:55:48| | |Connected to Redis.
FYI I'm using React Native as a frontend for all this and so far I got everything playing along nicely with Lighthouse, super amazed how lighthouse just delivers on the graphql backend part. I simply can't stop talking to people about this (even if they don't even have a clue)!
from lighthouse.
is there a way to fire subscriptions events without @event directive?
from lighthouse.
I love this!!!
from lighthouse.
Is this valid today? For version 4.0
from lighthouse.
Subscriptions are implemented as of Lighthouse v3.
from lighthouse.
using graphql-playground the next error appears:
"error": "Could not connect to websocket endpoint ws://localhost/project/public/graphql. Please check if the endpoint url is correct."
}```
from lighthouse.
Subscriptions in Lighthouse are based on the ruby implementation which is not supported by Playground (or any other GraphQL IDE that I'm aware of).
In order to make it work with Playground you would have to create your own websocket server which implements the same implementation as apollo-server. Similar to lighthouse-ws which has been depreciated.
from lighthouse.
from lighthouse.
Subscriptions in Lighthouse are based on the ruby implementation which is not supported by Playground (or any other GraphQL IDE that I'm aware of).
In order to make it work with Playground you would have to create your own websocket server which implements the same implementation as apollo-server. Similar to lighthouse-ws which has been depreciated.
@chrissm79
How can i create websocket server which connect with lighthouse graphql subscription ?
from lighthouse.
Subscriptions have been implemented for quite some time, so i am locking this issue. Use Slack or Stackoverflow for support questions. Bugs or new features can be adressed in either a new issue or a PR.
from lighthouse.
Related Issues (20)
- Segmentation fault when handling large payloads HOT 8
- Requesting local scopes can pass parameters HOT 1
- New directive that mirrors functionality of `whereHas` for relations (not `@whereHasConditions`) HOT 1
- `make setup` failed on macOS
- Access context in `FieldMiddleware` HOT 3
- CanArgs is defined twice in schema-directives.graphql
- `extend scalar X` directives are lost
- @canFind is missing "model" argument in graphql definition HOT 1
- Allow to customize the unique key for `PaginatedModelsLoader`
- artisan lighthouse:union stub appears to be incorrect HOT 1
- Problem with subscription middleware HOT 2
- An error occurs in the SubscriptionRegistry when sending a subscription event via Subscription::broadcast with Laravel Octane (Swoole) HOT 5
- Laravel v11 support dependancy missing
- Enum Support for Morph Types HOT 1
- Mutation transaction seem not work HOT 4
- Failed to find class App\GraphQl\Queries\TodoQuery in namespaces [] for directive @paginate
- @whereNull and @whereNotNull No directive found!
- GraphQL subscription with Laravel Reverb HOT 3
- input.id in @can(find: ) HOT 1
- Throttle directive sets wrong decay time HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lighthouse.