Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add todo example app with apollo #146

Closed
n1ru4l opened this issue Oct 8, 2020 · 10 comments · Fixed by #147
Closed

add todo example app with apollo #146

n1ru4l opened this issue Oct 8, 2020 · 10 comments · Fixed by #147

Comments

@n1ru4l
Copy link
Owner

n1ru4l commented Oct 8, 2020

In order to showcase and proof that @n1ru4l/socket-io-graphql-client works with apollo-client, adding the example app using apollo would be awesome :)

@Venryx
Copy link
Contributor

Venryx commented May 16, 2021

I was looking through the Apollo example, and noticed that it uses socket-io-graph-ql-client, rather than the built in HttpLink (from "@apollo/client") and WebSocketLink (from "@apollo/client/link/ws").

Is it possible to use graphql-live-query with the built-in HttpLink and WebSocketLink rather than socket-io-graph-ql-client?

If so, is there an example somewhere showing how to do so?

Venryx added a commit to Venryx/postgraphile-live-query-demos that referenced this issue May 16, 2021
@n1ru4l
Copy link
Owner Author

n1ru4l commented May 16, 2021

@Venryx apollo-link-http does afaik not support not long living http connections such as SSE or chunked delivery https://github.com/graphql/graphql-over-http/blob/main/rfcs/IncrementalDelivery.md)

So you would have to write your own link that supports this (and use a server library that supports it, such as graphql-helix).

When I started implementing graphql-live-query the ecosystem around transports was not well developed. That is one of the reasons why I created the graphql over sovket.io protocol which I also use for some of my applications.

Now we also have graphql-ws which also has full support for defer/stream and live queries.

You are not forced to use socket.io for transport.

The graphql-ws protocol is probably better battle-tested than my graphql over socket.io transport and most people should probably use graphql-ws .

I also do not recommend using the deprecated graphql-transport-ws (which is used by apollo-link-ws and apollo-server). Please use the stable and maintained graphql-ws package if you want to do subscriptions/live queries over websocket.

There is an example of how you can set up an apollo link that uses graphql-ws over here: https://github.com/enisdenjo/graphql-ws (this requires your server to also use the graphql-ws transport).

Over on https://github.com/n1ru4l/graphql-bleeding-edge-playground we have examples for server and client communication for GraphQL over HTTP via graphql-helix (with full defer/stream via chunked delivery and subscriptions and live queries via SSE), GraphQL over WebSocket (also with full defer/stream, subscription and live query support) via graphql-ws and GraphQL over Socket.io (also with full defer/stream, subscription and live query support) via @n1ru4l/socket-io-graphql-server/client.

Of course, the examples are not framework-specific, but you can easily wire them up to any client, exchanges for urql, request function for relay and link for apollo.

@Venryx
Copy link
Contributor

Venryx commented May 16, 2021

Yes, it's odd to me that the Apollo team is still using subscriptions-transport-ws, since like you mentioned, it's no longer being maintained. I hope they will switch their codebase to graphql-ws soon. If they take too long, I will look into making the switch manually.

That said, I was able to hack together a solution with the existing vanilla Apollo setup/dependencies, without needing the socket-io-graph-ql-client package.

Server code: https://github.com/Venryx/postgraphile-live-query-demos/blob/02cc0bba79044180f61f8bfbcac55c0d2f3203b3/Server/Utils/LQHelper.ts
Client code: https://github.com/Venryx/postgraphile-live-query-demos/blob/02cc0bba79044180f61f8bfbcac55c0d2f3203b3/Client/Utils/LibIntegrations/PGLink.ts

However, it is super ugly because I don't really know how to use "AsyncIterableIterator" generator functions. (for example, I just fiddled around with my fake iterator wrapper [aka monstrosity] on the client-side until it did what I wanted)

That very hacky code appears to be working though; it's successfully generating json-patches on the server, and applying them on the client, with a vanilla Apollo setup. (I've confirmed using dev-tools that only patch data is being sent)

However, based on what you've said, it sounds like there are various negative side-effects of using the outdated subscriptions-transport-ws protocol. Is the issue that the connection will disconnect after some time, even if the user is still active?

Or maybe you mean something else by:

apollo-link-http does afaik not support long living http connections such as SSE or chunked delivery

Are the limitations above show-stoppers? Or just not ideal?

(I would rather not change from the Apollo client's default transports and such unless/until I hit significant drawbacks with them.)

@n1ru4l
Copy link
Owner Author

n1ru4l commented May 16, 2021

How graphql-live-query and defer/stream are implemented on the "server"/executor is that the execute function which is used for executing mutations and query operations returns an AsyncIterator instead of a Promise (or sync value if no resolver is async).

If you want to implement the transport/executor on the server yourself you can use https://github.com/contrawork/graphql-helix, https://github.com/n1ru4l/graphql-live-query/tree/main/packages/socket-io-graphql-server or https://github.com/enisdenjo/graphql-ws as a reference.

I would however not recommend to do it yourself and rather pick one of those already existing solutions.

See https://the-guild.dev/blog/graphql-over-websockets or https://github.com/apollographql/subscriptions-transport-ws#graphql-ws on why you should not use subscriptions-transport-ws.

For Observable/AyncIterator/Sink interop I made this utility library: https://github.com/n1ru4l/push-pull-async-iterable-iterator It might be handy for your link. It also supports Safari iOS 14 which does not has Symbol.asyncIterator implemented.

Are the limitations above show-stoppers? Or just not ideal?

These are show stoppers as this does not allow to do subscriptions/defer/stream/live over http with the default http link (see apollographql/apollo-client#7691)

@Venryx
Copy link
Contributor

Venryx commented May 16, 2021

If you want to implement the transport/executor on the server yourself you can use https://github.com/contrawork/graphql-helix, https://github.com/n1ru4l/graphql-live-query/tree/main/packages/socket-io-graphql-server or https://github.com/enisdenjo/graphql-ws as a reference. [...]

For Observable/AyncIterator/Sink interop I made this utility library: https://github.com/n1ru4l/push-pull-async-iterable-iterator It might be handy for your link. It also supports Safari iOS 14 which does not has Symbol.asyncIterator implemented.

Okay, I will take a look at both the demos and that interop utility, as I try to clean up and package the working code.

(For context, I'm attempting to create a helper package for Postgraphile, utilizing graphql-live-query-patch to improve the efficiency of its live-query functionality, as discussed here.)

These are show stoppers as this does not allow to do subscriptions/defer/stream/live over http with the default http link (see apollographql/apollo-client#7691)

Ah, I see. The reason I haven't hit the issues yet is simply that I've only been using websocket-capable browsers, and so haven't hit the http-based fallback?

@n1ru4l
Copy link
Owner Author

n1ru4l commented May 16, 2021

Ah, I see. The reason I haven't hit the issues yet is simply that I've only been using websocket-capable browsers, and so haven't hit the http-based fallback?

I can not follow 100%. AFAIK there is no Apollo link that uses a WebSocket transport with HTTP fallback.

If you are referring to the GraphQL over Socket.io transport (link): Socket.io tries to establish a WebSocket connection and falls back to a polling solution.

Links are meant as pluggable building blocks. It allows wiring up to HTTP, WebSocket, or any other protocol you wanna do GraphQL over. E.g. in server-to-server communication, you could also do GraphQL over Redis. However, I would avoid using apollo-client for server-to-server communication

@Venryx
Copy link
Contributor

Venryx commented May 16, 2021

I can not follow 100%. AFAIK there is no Apollo link that uses a WebSocket transport with HTTP fallback.

Yes, my bad; the usage of httpLink and wsLink (as seen here) was for another purpose (handling for regular queries vs subscriptions). The wsLink there is based on @apollo/client/link/ws, which is presumably based on the subscriptions-transport-ws that you do not recommend.

I guess I'm wondering what is wrong with the subscriptions-transport-ws library. (as that one is currently the "default"/included as a dependency of the @apollo/client package)

Is it mainly just that its deprecated, and so will increasingly fall behind in features and stability over time?

@n1ru4l
Copy link
Owner Author

n1ru4l commented May 16, 2021

I guess I'm wondering what is wrong with the subscriptions-transport-ws library. Is it mainly just that its deprecated, and so will increasingly fall behind in features and stability over time?

The reasons why I think you should not use it:

  1. No active maintainers (200+ open issues https://github.com/apollographql/subscriptions-transport-ws/issues)
  2. Deprecated
  3. It has unnecessary dependencies (https://github.com/apollographql/subscriptions-transport-ws/blob/0cdf55b5f3f5ddca99f9a056ab5fa0cf94a66591/package.json#L12-L15)
  4. Security concerns listed over here: Issues and security implications with subscriptions-transport-ws enisdenjo/graphql-ws#3

@Venryx
Copy link
Contributor

Venryx commented May 16, 2021

Thanks. I'll keep those points in mind, and switch to another transport at some point (eg. before production).

@Venryx
Copy link
Contributor

Venryx commented May 20, 2021

By the way, I've finished published a working set of packages that add the json-patch/send-delta-only functionality between Postgraphile (backend) and Apollo (frontend): https://github.com/pg-lq/postgraphile-live-query

Discussion thread here. (still needs a pull-request in postgraphile's upstream for easy installation)

There's still some clean-up work I need to do (eg. regarding the async-iterator code), but as-is, it does work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants