-
-
Notifications
You must be signed in to change notification settings - Fork 22
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
feat(handler): Server and environment agnostic handler #37
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enisdenjo
pushed a commit
that referenced
this pull request
Dec 20, 2022
# [2.0.0](v1.3.2...v2.0.0) (2022-12-20) ### Features * **handler:** Server and environment agnostic handler ([#37](#37)) ([22cf03d](22cf03d)) ### BREAKING CHANGES * **handler:** The handler is now server agnostic and can run _anywhere_ - Core of `graphql-sse` is now server agnostic and as such offers a handler that implements a generic request/response model - Handler does not await for whole operation to complete anymore. Only the processing part (parsing, validating and executing) - GraphQL context is now typed - Hook arguments have been changed, they're not providing the Node native req/res anymore - they instead provide the generic request/response - `onSubscribe` hook can now return an execution result too (useful for caching for example) - Throwing in `onNext` and `onComplete` hooks will bubble the error to the returned iterator ### Migration Even though the core of graphql-sse is now completely server agnostic, there are adapters to ease the integration with existing solutions. Migrating is actually not a headache! Beware that the adapters **don't** handle internal errors, it's your responsibility to take care of that and behave accordingly. #### [`http`](https://nodejs.org/api/http.html) ```diff import http from 'http'; - import { createHandler } from 'graphql-sse'; + import { createHandler } from 'graphql-sse/lib/use/http'; // Create the GraphQL over SSE handler const handler = createHandler({ schema }); // Create an HTTP server using the handler on `/graphql/stream` const server = http.createServer((req, res) => { if (req.url.startsWith('/graphql/stream')) { return handler(req, res); } res.writeHead(404).end(); }); server.listen(4000); console.log('Listening to port 4000'); ``` #### [`http2`](https://nodejs.org/api/http2.html) ```diff import fs from 'fs'; import http2 from 'http2'; - import { createHandler } from 'graphql-sse'; + import { createHandler } from 'graphql-sse/lib/use/http2'; // Create the GraphQL over SSE handler const handler = createHandler({ schema }); // Create an HTTP server using the handler on `/graphql/stream` const server = http.createServer((req, res) => { if (req.url.startsWith('/graphql/stream')) { return handler(req, res); } res.writeHead(404).end(); }); server.listen(4000); console.log('Listening to port 4000'); ``` #### [`express`](https://expressjs.com/) ```diff import express from 'express'; // yarn add express - import { createHandler } from 'graphql-sse'; + import { createHandler } from 'graphql-sse/lib/use/express'; // Create the GraphQL over SSE handler const handler = createHandler({ schema }); // Create an express app const app = express(); // Serve all methods on `/graphql/stream` app.use('/graphql/stream', handler); server.listen(4000); console.log('Listening to port 4000'); ``` #### [`fastify`](https://www.fastify.io/) ```diff import Fastify from 'fastify'; // yarn add fastify - import { createHandler } from 'graphql-sse'; + import { createHandler } from 'graphql-sse/lib/use/fastify'; // Create the GraphQL over SSE handler const handler = createHandler({ schema }); // Create a fastify app const fastify = Fastify(); // Serve all methods on `/graphql/stream` fastify.all('/graphql/stream', handler); fastify.listen({ port: 4000 }); console.log('Listening to port 4000'); ```
🎉 This PR is included in version 2.0.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
pholuj-candis
pushed a commit
to CandisIO/graphql-sse
that referenced
this pull request
Oct 10, 2024
# 1.0.0 (2024-10-10) ### Bug Fixes * Add file extensions to imports/exports in ESM type definitions ([bbf23b1](bbf23b1)) * Add koa exports to package.json ([enisdenjo#85](https://github.com/CandisIO/graphql-sse/issues/85)) ([e99cf99](e99cf99)) * Add support for `graphql@v16` ([89367f2](89367f2)) * Add types path to package.json `exports` ([44f95b6](44f95b6)) * Bump `graphql` version to v16 in package.json ([af219f9](af219f9)) * **client:** Abort request when reporting error ([91057bd](91057bd)) * **client:** Avoid bundling DOM types, have the implementor supply his own `Response` type ([98780c0](98780c0)) * **client:** Leverage active streams for reliable network error retries ([607b468](607b468)) * **client:** Network errors during event emission contain the keyword "stream" in Firefox ([054f16b](054f16b)) * **client:** Operation requests are of application/json content-type ([0084de7](0084de7)) * **client:** Respect retry attempts when server goes away after connecting ([enisdenjo#57](https://github.com/CandisIO/graphql-sse/issues/57)) ([75c9f17](75c9f17)), closes [enisdenjo#55](https://github.com/CandisIO/graphql-sse/issues/55) * **client:** Respect retry attempts when server goes away after connecting in single connection mode ([enisdenjo#59](https://github.com/CandisIO/graphql-sse/issues/59)) ([e895c5b](e895c5b)), closes [enisdenjo#55](https://github.com/CandisIO/graphql-sse/issues/55) * **client:** Retry if connection is closed while having active streams ([83a0178](83a0178)), closes [enisdenjo#28](https://github.com/CandisIO/graphql-sse/issues/28) * **client:** Retry network errors even if they occur during event emission ([489b1b0](489b1b0)), closes [enisdenjo#27](https://github.com/CandisIO/graphql-sse/issues/27) * **client:** Should not call complete after subscription error ([d8b7634](d8b7634)) * **client:** TypeScript generic for ensuring proper arguments when using "single connection mode" ([be2ae7d](be2ae7d)) * **client:** Use closures instead of bindings (with `this`) ([8ecdf3c](8ecdf3c)) * Define graphql execution results ([89da803](89da803)) * **handler:** Always include the `data` field in stream messages ([enisdenjo#71](https://github.com/CandisIO/graphql-sse/issues/71)) ([4643c9a](4643c9a)) * **handler:** Correct typings and support for http2 ([08d6ca3](08d6ca3)), closes [enisdenjo#38](https://github.com/CandisIO/graphql-sse/issues/38) * **handler:** Detect `ExecutionArgs` in `onSubscribe` return value ([a16b921](a16b921)), closes [enisdenjo#58](https://github.com/CandisIO/graphql-sse/issues/58) * **handler:** Support generics for requests and responses ([9ab10c0](9ab10c0)) * **handler:** Use 3rd `body` argument only if is object or string ([2062579](2062579)) * Prefer `X-GraphQL-Event-Stream-Token` header name for clarity ([9aaa0a9](9aaa0a9)) * remove package.json workspaces entry in release ([c6dc093](c6dc093)) * Request parameters `query` field can only be a string ([16c9600](16c9600)), closes [enisdenjo#65](https://github.com/CandisIO/graphql-sse/issues/65) * **server:** Operation result can be async generator or iterable ([24b6078](24b6078)) * **use/express,use/fastify:** Resolve body if previously parsed ([6573e94](6573e94)) * **use/express:** make sure that we not send something through previously closed stream ([e4b8c5f](e4b8c5f)) * **use/fastify:** Include middleware headers ([134c1b0](134c1b0)), closes [enisdenjo#91](https://github.com/CandisIO/graphql-sse/issues/91) * **use/http,use/http2,use/express,use/fastify:** Check `writable` instead of `closed` before writing to response ([3c71f69](3c71f69)), closes [enisdenjo#69](https://github.com/CandisIO/graphql-sse/issues/69) * **use/http,use/http2,use/express,use/fastify:** Handle cases where response's `close` event is late ([enisdenjo#75](https://github.com/CandisIO/graphql-sse/issues/75)) ([4457cba](4457cba)), closes [enisdenjo#69](https://github.com/CandisIO/graphql-sse/issues/69) * **use/koa:** Use parsed body from request ([enisdenjo#87](https://github.com/CandisIO/graphql-sse/issues/87)) ([b290b90](b290b90)) ### Features * Client ([enisdenjo#3](https://github.com/CandisIO/graphql-sse/issues/3)) ([754487d](754487d)) * **client:** Accept `referrer` and `referrerPolicy` fetch options ([enisdenjo#32](https://github.com/CandisIO/graphql-sse/issues/32)) ([dbaa90a](dbaa90a)) * **client:** Add `credentials` property for requests ([79d0266](79d0266)) * **client:** Add `lazyCloseTimeout` as a close timeout after last operation completes ([16e5e31](16e5e31)), closes [enisdenjo#17](https://github.com/CandisIO/graphql-sse/issues/17) * **client:** Async iterator for subscriptions ([enisdenjo#66](https://github.com/CandisIO/graphql-sse/issues/66)) ([fb8bf11](fb8bf11)) * **client:** Event listeners for both operation modes ([enisdenjo#84](https://github.com/CandisIO/graphql-sse/issues/84)) ([6274f44](6274f44)) * **client:** Inspect incoming messages through `ClientOptions.onMessage` ([496e74b](496e74b)), closes [enisdenjo#20](https://github.com/CandisIO/graphql-sse/issues/20) * **handler:** Export handler options type for each integration ([2a2e517](2a2e517)) * **handler:** Server and environment agnostic handler ([enisdenjo#37](https://github.com/CandisIO/graphql-sse/issues/37)) ([22cf03d](22cf03d)) * **handler:** Use Koa ([enisdenjo#80](https://github.com/CandisIO/graphql-sse/issues/80)) ([283b453](283b453)), closes [enisdenjo#78](https://github.com/CandisIO/graphql-sse/issues/78) * Server request handler ([enisdenjo#2](https://github.com/CandisIO/graphql-sse/issues/2)) ([8381796](8381796)) * **use/koa:** expose full Koa context to options ([enisdenjo#86](https://github.com/CandisIO/graphql-sse/issues/86)) ([b37a6f9](b37a6f9)) ### Performance Improvements * **client:** Avoid recreating result variables when reading the response stream ([16f6a6c](16f6a6c)) ### BREAKING CHANGES * **handler:** The handler is now server agnostic and can run _anywhere_ - Core of `graphql-sse` is now server agnostic and as such offers a handler that implements a generic request/response model - Handler does not await for whole operation to complete anymore. Only the processing part (parsing, validating and executing) - GraphQL context is now typed - Hook arguments have been changed, they're not providing the Node native req/res anymore - they instead provide the generic request/response - `onSubscribe` hook can now return an execution result too (useful for caching for example) - Throwing in `onNext` and `onComplete` hooks will bubble the error to the returned iterator ### Migration Even though the core of graphql-sse is now completely server agnostic, there are adapters to ease the integration with existing solutions. Migrating is actually not a headache! Beware that the adapters **don't** handle internal errors, it's your responsibility to take care of that and behave accordingly. #### [`http`](https://nodejs.org/api/http.html) ```diff import http from 'http'; - import { createHandler } from 'graphql-sse'; + import { createHandler } from 'graphql-sse/lib/use/http'; // Create the GraphQL over SSE handler const handler = createHandler({ schema }); // Create an HTTP server using the handler on `/graphql/stream` const server = http.createServer((req, res) => { if (req.url.startsWith('/graphql/stream')) { return handler(req, res); } res.writeHead(404).end(); }); server.listen(4000); console.log('Listening to port 4000'); ``` #### [`http2`](https://nodejs.org/api/http2.html) ```diff import fs from 'fs'; import http2 from 'http2'; - import { createHandler } from 'graphql-sse'; + import { createHandler } from 'graphql-sse/lib/use/http2'; // Create the GraphQL over SSE handler const handler = createHandler({ schema }); // Create an HTTP server using the handler on `/graphql/stream` const server = http.createServer((req, res) => { if (req.url.startsWith('/graphql/stream')) { return handler(req, res); } res.writeHead(404).end(); }); server.listen(4000); console.log('Listening to port 4000'); ``` #### [`express`](https://expressjs.com/) ```diff import express from 'express'; // yarn add express - import { createHandler } from 'graphql-sse'; + import { createHandler } from 'graphql-sse/lib/use/express'; // Create the GraphQL over SSE handler const handler = createHandler({ schema }); // Create an express app const app = express(); // Serve all methods on `/graphql/stream` app.use('/graphql/stream', handler); server.listen(4000); console.log('Listening to port 4000'); ``` #### [`fastify`](https://www.fastify.io/) ```diff import Fastify from 'fastify'; // yarn add fastify - import { createHandler } from 'graphql-sse'; + import { createHandler } from 'graphql-sse/lib/use/fastify'; // Create the GraphQL over SSE handler const handler = createHandler({ schema }); // Create a fastify app const fastify = Fastify(); // Serve all methods on `/graphql/stream` fastify.all('/graphql/stream', handler); fastify.listen({ port: 4000 }); console.log('Listening to port 4000'); ```
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Breaking changes
graphql-sse
is now server agnostic and as such offers a handler that implements a generic request/response modelonSubscribe
hook can now return an execution result too (useful for caching for example)onNext
andonComplete
hooks will bubble the error to the returned iteratorMigration
Even though the core of graphql-sse is now completely server agnostic, there are adapters to ease the integration with existing solutions. Migrating is actually not a headache!
Beware that the adapters don't handle internal errors, it's your responsibility to take care of that and behave accordingly.
http
http2
express
fastify
TODO
use/fetch
adapteruse/http
adapteruse/http2
adapteruse/express
adapteruse/fastify
adapter