graphiql icon indicating copy to clipboard operation
graphiql copied to clipboard

[graphiql] SSE support for subscriptions ?

Open divad1196 opened this issue 8 months ago • 2 comments

Hi,

Thank you for the work.
I just implemented subscription with SSE (Server Side Event) on my server but it seems that it's not support or I didn't find any documentation on that matter..

I hoped to have an option on the fetch but it seems that it only supports websockets ?

Would it be possible for GraphiQL to support SSE as well?

divad1196 avatar Jun 15 '25 21:06 divad1196

@divad1196 based on this example i've ended up with something like this for fetcher:

      const httpFetcher = createGraphiQLFetcher({ url: window.location });
      let headers = {};
      const sseClient = createClient({
        url: window.location,
        headers: () => headers,
      });
      const fetcher = (payload, opts) => {
        if (!payload.query.trim().startsWith("subscription")) {
          return httpFetcher(payload, opts);
        }
        
        headers = opts.headers;
        let deferred = null;
        const pending = [];
        let throwMe = null,
          done = false;
        const dispose = sseClient.subscribe(payload, {
          next: (data) => {
            pending.push(data);
            deferred?.resolve(false);
          },
          error: (err) => {
            throwMe = err;
            deferred?.reject(throwMe);
          },
          complete: () => {
            done = true;
            deferred?.resolve(true);
          },
        });
        return {
          [Symbol.asyncIterator]() {
            return this;
          },
          async next() {
            if (done) return { done: true, value: undefined };
            if (throwMe) throw throwMe;
            if (pending.length) return { value: pending.shift() };
            return (await new Promise(
              (resolve, reject) => (deferred = { resolve, reject })
            ))
              ? { done: true, value: undefined }
              : { value: pending.shift() };
          },
          async return() {
            dispose();
            return { done: true, value: undefined };
          },
        };
      }

createClient - exported by graphql-sse, so don't forget to import it

Rusty-Beard avatar Jun 24 '25 11:06 Rusty-Beard

Hi,

Thank you

I had something similar but without relying on intermediate library. This issue is not just to develop it myself but more that it could be integrated in graphiql directly.

divad1196 avatar Jun 24 '25 12:06 divad1196