Skip to content

Commit 7aad3d3

Browse files
committed
docs: add an SSE example
1 parent 0d9f062 commit 7aad3d3

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

docs/guide.md

+46
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
- [Async operations](#async-operations)
1717
- [Debugging Koa](#debugging-koa)
1818
- [HTTP2](#http2)
19+
- [Server-Side Events](#server-side-events)
1920

2021
## Writing Middleware
2122

@@ -267,3 +268,48 @@ const serverOptions = {
267268

268269
const server = http2.createSecureServer(serverOptions, onRequestHandler);
269270
```
271+
272+
## Server-Side Events
273+
274+
An example of using server-side events with Koa:
275+
276+
```js
277+
import PassThrough from 'stream'
278+
import OpenAI from 'openai'
279+
import Koa from 'koa'
280+
281+
const openai = new OpenAI({
282+
apiKey: process.env.OPENAI_API_KEY,
283+
})
284+
285+
const app = new Koa()
286+
287+
app.use(async (ctx, next) => { // TODO: use your favorite routing library
288+
const { message } = await ctx.request.json() // this example uses koa-body-parsers
289+
290+
const stream = await client.chat.completions.create({
291+
model: 'gpt-4o-mini',
292+
messages: [{ role: 'user', content: messages }],
293+
stream: true,
294+
})
295+
296+
ctx.response.type = 'text/event-stream'
297+
const body = ctx.body = new PassThrough()
298+
299+
// streaming needs to be handled in a separate event loop
300+
;(async () => {
301+
for await (const chunk of stream) {
302+
const content = chunk.choices[0]?.delta?.content
303+
if (!content) continue
304+
305+
body.write(`data: ${JSON.stringify({
306+
delta: {
307+
content: chunk.choices[0].delta.content || ''
308+
}
309+
})}}\n\n`)
310+
311+
body.end()
312+
}
313+
})().catch((err) => app.emit('error', err))
314+
})
315+
```

0 commit comments

Comments
 (0)