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

Fix fetch duplex docs #3422

Merged
merged 1 commit into from
Jul 26, 2024
Merged

Fix fetch duplex docs #3422

merged 1 commit into from
Jul 26, 2024

Conversation

Ethan-Arrowood
Copy link
Collaborator

I've been toying with the duplex option, and I noticed our docs are a little confusing. The implementation forces me to use 'half' for the value, but it seem like a full duplex operation... unless the 'full' duplex refers to just the request or response individually?

It's a bit confusing.

WDYT @KhafraDev ?

@Ethan-Arrowood
Copy link
Collaborator Author

I wrote up this example:

import http from 'node:http';
import events from 'node:events';
import timers from 'node:timers/promises';

// Create a ReadableStream
const stream = new ReadableStream({
  async start(controller) {
		const chunks = ['Hello', ' ', 'World', '!'];
		for (const chunk of chunks) {
			controller.enqueue(chunk);
			await timers.setTimeout(500);
		}
		controller.close();
  }
});

const server = http.createServer((req, res) => {
	// Gather important information about the request
	const requestInfo = {
		method: req.method,
		url: req.url,
		headers: req.headers,
	};

	// Print the request information
	console.log('Incoming Request:');
	console.log(JSON.stringify(requestInfo, null, 2));

	if (req.method === 'POST') {
		res.writeHead(200, {
			// 'Content-Type': 'text/plain',
			'transfer-encoding': 'chunked'
		})

		req.on('data', (chunk) => {
			console.log('Server Received Chunk:', chunk);
			res.write(chunk);
		})

		req.on('end', ()=> {
			console.log('Server Request Ended');
			res.end();
		})
	} else {
			res.writeHead(200, { 'Content-Type': 'text/plain' });
			res.end('200 OK');
	}
});

server.listen(3000);

await events.once(server, 'listening');

const data = {
  async *[Symbol.asyncIterator]() {
    yield 'hello'
    yield 'world'
  },
}

const response = await fetch('http://localhost:3000', {
  method: 'POST',
  body: stream,
  duplex: 'half'
});

const reader = response.body.getReader();

while (true) {
	const { done, value } = await reader.read();
	if (done) break;
	console.log('Client Received Chunk:', value);
}

server.close();

And it prints out:

Incoming Request:
{
  "method": "POST",
  "url": "/",
  "headers": {
    "host": "localhost:3000",
    "connection": "keep-alive",
    "accept": "*/*",
    "accept-language": "*",
    "sec-fetch-mode": "cors",
    "user-agent": "node",
    "accept-encoding": "gzip, deflate",
    "transfer-encoding": "chunked"
  }
}
Server Received Chunk: <Buffer 48 65 6c 6c 6f>
Client Received Chunk: Uint8Array(5) [ 72, 101, 108, 108, 111 ]
Server Received Chunk: <Buffer 20>
Client Received Chunk: Uint8Array(1) [ 32 ]
Server Received Chunk: <Buffer 57 6f 72 6c 64>
Client Received Chunk: Uint8Array(5) [ 87, 111, 114, 108, 100 ]
Server Received Chunk: <Buffer 21>
Client Received Chunk: Uint8Array(1) [ 33 ]
Server Request Ended

Copy link
Member

@KhafraDev KhafraDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fetch requests are meant to be half-duplex and the duplex option was added to eventually add support for full-duplex requests. Requests in undici are always full-duplex, so our fetch inherited this behavior.

@Ethan-Arrowood
Copy link
Collaborator Author

Cool, sounds good to me!

@Ethan-Arrowood Ethan-Arrowood merged commit 0f45d42 into main Jul 26, 2024
36 checks passed
@Uzlopak Uzlopak deleted the fix-fetch-duplex-docs branch August 1, 2024 09:57
@github-actions github-actions bot mentioned this pull request Dec 3, 2024
This was referenced Dec 16, 2024
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 this pull request may close these issues.

2 participants